From f860366456d9e59b139a940da6d89c3c4fb9e96e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 30 Jul 2012 02:38:39 -0400 Subject: [PATCH] [OT] Gain back some lost speed --- src/hb-ot-layout-private.hh | 27 ++++++++++++- src/hb-ot-layout.cc | 63 +++++++++++++++++++++++++++--- src/hb-ot-map-private.hh | 26 +++--------- src/hb-ot-map.cc | 35 ++++++++++++----- src/hb-ot-shape-complex-indic.cc | 2 +- src/hb-ot-shape-complex-private.hh | 5 --- 6 files changed, 114 insertions(+), 44 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 705fe67b6..78c9d64dd 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -1,5 +1,6 @@ /* * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -22,6 +23,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod */ #ifndef HB_OT_LAYOUT_PRIVATE_HH @@ -33,9 +35,13 @@ #include "hb-font-private.hh" #include "hb-buffer-private.hh" -#include "hb-ot-shape-complex-private.hh" +/* buffer var allocations, used during the GSUB/GPOS processing */ +#define props_cache() var1.u16[1] /* GSUB/GPOS glyph_props cache */ +#define syllable() var2.u8[0] /* GSUB/GPOS shaping boundaries */ +#define lig_props() var2.u8[1] /* GSUB/GPOS ligature tracking */ + #define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot) /* @@ -142,6 +148,25 @@ static inline uint8_t allocate_lig_id (hb_buffer_t *buffer) { } +HB_INTERNAL hb_bool_t +hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face, + const hb_codepoint_t *glyphs, + unsigned int glyphs_length, + unsigned int lookup_index); + +HB_INTERNAL hb_bool_t +hb_ot_layout_substitute_lookup_fast (hb_face_t *face, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask); + +HB_INTERNAL hb_bool_t +hb_ot_layout_position_lookup_fast (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask); + + /* * hb_ot_layout_t */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index c7f1f09c7..617034bd6 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2,6 +2,7 @@ * Copyright © 1998-2004 David Turner and Werner Lemberg * Copyright © 2006 Behdad Esfahbod * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -24,6 +25,7 @@ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod */ #include "hb-ot-layout-private.hh" @@ -93,6 +95,24 @@ _get_gpos (hb_face_t *face) return *hb_ot_layout_from_face (face)->gpos; } +static inline const GDEF& +_get_gdef_fast (hb_face_t *face) +{ + return *hb_ot_layout_from_face (face)->gdef; +} +static inline const GSUB& +_get_gsub_fast (hb_face_t *face) +{ + if (unlikely (!hb_ot_layout_ensure (face))) return Null(GSUB); + return *hb_ot_layout_from_face (face)->gsub; +} +static inline const GPOS& +_get_gpos_fast (hb_face_t *face) +{ + if (unlikely (!hb_ot_layout_ensure (face))) return Null(GPOS); + return *hb_ot_layout_from_face (face)->gpos; +} + /* * GDEF @@ -110,7 +130,7 @@ _hb_ot_layout_get_glyph_property (hb_face_t *face, { if (!info->props_cache()) { - const GDEF &gdef = _get_gdef (face); + const GDEF &gdef = _get_gdef_fast (face); info->props_cache() = gdef.get_glyph_props (info->codepoint); } @@ -127,7 +147,7 @@ _hb_ot_layout_match_properties_mark (hb_face_t *face, * lookup_props has the set index. */ if (lookup_props & LookupFlag::UseMarkFilteringSet) - return _get_gdef (face).mark_set_covers (lookup_props >> 16, glyph); + return _get_gdef_fast (face).mark_set_covers (lookup_props >> 16, glyph); /* The second byte of lookup_props has the meaning * "ignore marks of attachment type different than @@ -479,6 +499,17 @@ hb_ot_layout_would_substitute_lookup (hb_face_t *face, return _get_gsub (face).would_substitute_lookup (&c, lookup_index); } +hb_bool_t +hb_ot_layout_would_substitute_lookup_fast (hb_face_t *face, + const hb_codepoint_t *glyphs, + unsigned int glyphs_length, + unsigned int lookup_index) +{ + if (unlikely (glyphs_length < 1 || glyphs_length > 2)) return false; + hb_would_apply_context_t c (face, glyphs[0], glyphs_length == 2 ? glyphs[1] : -1); + return _get_gsub_fast (face).would_substitute_lookup (&c, lookup_index); +} + void hb_ot_layout_substitute_start (hb_buffer_t *buffer) { @@ -495,6 +526,16 @@ hb_ot_layout_substitute_lookup (hb_face_t *face, return _get_gsub (face).substitute_lookup (&c, lookup_index); } +hb_bool_t +hb_ot_layout_substitute_lookup_fast (hb_face_t *face, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask) +{ + hb_apply_context_t c (NULL, face, buffer, mask); + return _get_gsub_fast (face).substitute_lookup (&c, lookup_index); +} + void hb_ot_layout_substitute_finish (hb_buffer_t *buffer HB_UNUSED) { @@ -527,15 +568,25 @@ hb_ot_layout_position_start (hb_buffer_t *buffer) } hb_bool_t -hb_ot_layout_position_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask) +hb_ot_layout_position_lookup (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask) { hb_apply_context_t c (font, font->face, buffer, mask); return _get_gpos (font->face).position_lookup (&c, lookup_index); } +hb_bool_t +hb_ot_layout_position_lookup_fast (hb_font_t *font, + hb_buffer_t *buffer, + unsigned int lookup_index, + hb_mask_t mask) +{ + hb_apply_context_t c (font, font->face, buffer, mask); + return _get_gpos_fast (font->face).position_lookup (&c, lookup_index); +} + void hb_ot_layout_position_finish (hb_buffer_t *buffer) { diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index d098c750f..2ba0f767a 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -1,6 +1,6 @@ /* * Copyright © 2009,2010 Red Hat, Inc. - * Copyright © 2010,2011 Google, Inc. + * Copyright © 2010,2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -31,8 +31,7 @@ #include "hb-buffer-private.hh" -#include "hb-ot-layout.h" - +#include "hb-ot-layout-private.hh" static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS}; @@ -69,14 +68,9 @@ struct hb_ot_map_t inline hb_tag_t get_chosen_script (unsigned int table_index) const { return chosen_script[table_index]; } - inline void substitute (hb_face_t *face, hb_buffer_t *buffer) const - { apply (0, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_substitute_lookup, face, buffer); } - inline void position (hb_font_t *font, hb_buffer_t *buffer) const - { apply (1, (hb_ot_map_t::apply_lookup_func_t) hb_ot_layout_position_lookup, font, buffer); } - - HB_INTERNAL void substitute_closure (hb_face_t *face, - hb_set_t *glyphs) const; - + HB_INTERNAL void substitute_closure (hb_face_t *face, hb_set_t *glyphs) const; + HB_INTERNAL void substitute (hb_face_t *face, hb_buffer_t *buffer) const; + HB_INTERNAL void position (hb_font_t *font, hb_buffer_t *buffer) const; inline void finish (void) { features.finish (); @@ -119,21 +113,11 @@ struct hb_ot_map_t pause_callback_t callback; }; - typedef hb_bool_t (*apply_lookup_func_t) (void *face_or_font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask); - HB_INTERNAL void add_lookups (hb_face_t *face, unsigned int table_index, unsigned int feature_index, hb_mask_t mask); - HB_INTERNAL void apply (unsigned int table_index, - hb_ot_map_t::apply_lookup_func_t apply_lookup_func, - void *face_or_font, - hb_buffer_t *buffer) const; - hb_mask_t global_mask; hb_tag_t chosen_script[2]; diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index d34160c55..20e8e6f55 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -31,7 +31,6 @@ #include "hb-ot-shape-private.hh" - void hb_ot_map_t::add_lookups (hb_face_t *face, unsigned int table_index, @@ -76,26 +75,42 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, bool gl info->stage[1] = current_stage[1]; } -void hb_ot_map_t::apply (unsigned int table_index, - hb_ot_map_t::apply_lookup_func_t apply_lookup_func, - void *face_or_font, - hb_buffer_t *buffer) const +/* Keep the next two functions in sync. */ + +void hb_ot_map_t::substitute (hb_face_t *face, hb_buffer_t *buffer) const { + const unsigned int table_index = 0; unsigned int i = 0; for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { const pause_map_t *pause = &pauses[table_index][pause_index]; for (; i < pause->num_lookups; i++) - apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); + hb_ot_layout_substitute_lookup_fast (face, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); - if (table_index == 0) - buffer->clear_output (); + buffer->clear_output (); - pause->callback.func (this, face_or_font, buffer, pause->callback.user_data); + pause->callback.func (this, face, buffer, pause->callback.user_data); } for (; i < lookups[table_index].len; i++) - apply_lookup_func (face_or_font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); + hb_ot_layout_substitute_lookup_fast (face, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); +} + +void hb_ot_map_t::position (hb_font_t *font, hb_buffer_t *buffer) const +{ + const unsigned int table_index = 1; + unsigned int i = 0; + + for (unsigned int pause_index = 0; pause_index < pauses[table_index].len; pause_index++) { + const pause_map_t *pause = &pauses[table_index][pause_index]; + for (; i < pause->num_lookups; i++) + hb_ot_layout_position_lookup_fast (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); + + pause->callback.func (this, font, buffer, pause->callback.user_data); + } + + for (; i < lookups[table_index].len; i++) + hb_ot_layout_position_lookup_fast (font, buffer, lookups[table_index][i].index, lookups[table_index][i].mask); } void hb_ot_map_t::substitute_closure (hb_face_t *face, diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index ea5648a2a..e4c151aac 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -105,7 +105,7 @@ would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count, lookup_indices); for (unsigned int i = 0; i < len; i++) - if (hb_ot_layout_would_substitute_lookup (face, glyphs, glyphs_count, lookup_indices[i])) + if (hb_ot_layout_would_substitute_lookup_fast (face, glyphs, glyphs_count, lookup_indices[i])) return true; offset += len; diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index 867a3c2bf..d444cd6b6 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -38,11 +38,6 @@ #define unicode_props0() var1.u8[0] #define unicode_props1() var1.u8[1] -/* buffer var allocations, used during the GSUB/GPOS processing */ -#define props_cache() var1.u16[1] /* GSUB/GPOS glyph_props cache */ -#define syllable() var2.u8[0] /* GSUB/GPOS shaping boundaries */ -#define lig_props() var2.u8[1] /* GSUB/GPOS ligature tracking */ - /* buffer var allocations, used by complex shapers */ #define complex_var_persistent_u8_0() var2.u8[2] #define complex_var_persistent_u8_1() var2.u8[3]