From 76ea563673d24ae1673a5aa3a21da6014479d433 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 4 May 2013 16:01:20 -0400 Subject: [PATCH 1/9] [OTLayout] Add note about collect_glyphs() and recursive lookups --- src/hb-ot-layout-gsubgpos-private.hh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index f46b3782e..5a5bce334 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -158,7 +158,13 @@ struct hb_collect_glyphs_context_t /* Note that GPOS sets recurse_func to NULL already, so it doesn't get * past the previous check. For GSUB, we only want to collect the output - * glyphs in the recursion. If output is not requested, we can go home now. */ + * glyphs in the recursion. If output is not requested, we can go home now. + * + * Note further, that the above is not exactly correct. A recursed lookup + * is allowed to match input that is not matched in the context, but that's + * not how most fonts are built. It's possible to relax that and recurse + * with all sets here if it proves to be an issue. + */ if (output == hb_set_get_empty ()) return HB_VOID; From 45fd9424c723f115ca98995b8f8a25185a6fc71d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2013 18:06:51 -0400 Subject: [PATCH 2/9] [OTLayout] Add hb_ot_layout_lookup_accelerator_t --- src/hb-ot-layout-private.hh | 21 ++++++++++++-- src/hb-ot-layout.cc | 33 +++++++++++----------- src/hb-ot-shape-complex-arabic-fallback.hh | 10 ++++--- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index 4866c4191..bd01078ee 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -244,6 +244,23 @@ namespace OT { struct GPOS; } +struct hb_ot_layout_lookup_accelerator_t +{ + template + inline void init (const TLookup &lookup) + { + digest.init (); + lookup.add_coverage (&digest); + } + + template + inline void fini (const TLookup &lookup) + { + } + + hb_set_digest_t digest; +}; + struct hb_ot_layout_t { hb_blob_t *gdef_blob; @@ -257,8 +274,8 @@ struct hb_ot_layout_t unsigned int gsub_lookup_count; unsigned int gpos_lookup_count; - hb_set_digest_t *gsub_digests; - hb_set_digest_t *gpos_digests; + hb_ot_layout_lookup_accelerator_t *gsub_accels; + hb_ot_layout_lookup_accelerator_t *gpos_accels; }; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index c80ca7d7f..76a6256e4 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -59,26 +59,20 @@ _hb_ot_layout_create (hb_face_t *face) layout->gsub_lookup_count = layout->gsub->get_lookup_count (); layout->gpos_lookup_count = layout->gpos->get_lookup_count (); - layout->gsub_digests = (hb_set_digest_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_set_digest_t)); - layout->gpos_digests = (hb_set_digest_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_set_digest_t)); + layout->gsub_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gsub->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); + layout->gpos_accels = (hb_ot_layout_lookup_accelerator_t *) calloc (layout->gpos->get_lookup_count (), sizeof (hb_ot_layout_lookup_accelerator_t)); - if (unlikely ((layout->gsub_lookup_count && !layout->gsub_digests) || - (layout->gpos_lookup_count && !layout->gpos_digests))) + if (unlikely ((layout->gsub_lookup_count && !layout->gsub_accels) || + (layout->gpos_lookup_count && !layout->gpos_accels))) { _hb_ot_layout_destroy (layout); return NULL; } for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) - { - layout->gsub_digests[i].init (); - layout->gsub->get_lookup (i).add_coverage (&layout->gsub_digests[i]); - } + layout->gsub_accels[i].init (layout->gsub->get_lookup (i)); for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) - { - layout->gpos_digests[i].init (); - layout->gpos->get_lookup (i).add_coverage (&layout->gpos_digests[i]); - } + layout->gpos_accels[i].init (layout->gpos->get_lookup (i)); return layout; } @@ -90,8 +84,13 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout) hb_blob_destroy (layout->gsub_blob); hb_blob_destroy (layout->gpos_blob); - free (layout->gsub_digests); - free (layout->gpos_digests); + for (unsigned int i = 0; i < layout->gsub_lookup_count; i++) + layout->gsub_accels[i].fini (layout->gsub->get_lookup (i)); + for (unsigned int i = 0; i < layout->gpos_lookup_count; i++) + layout->gpos_accels[i].fini (layout->gpos->get_lookup (i)); + + free (layout->gsub_accels); + free (layout->gpos_accels); free (layout); } @@ -659,7 +658,7 @@ hb_ot_layout_lookup_would_substitute_fast (hb_face_t *face, const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_digests[lookup_index]); + return l.would_apply (&c, &hb_ot_layout_from_face (face)->gsub_accels[lookup_index].digest); } void @@ -681,7 +680,7 @@ hb_ot_layout_substitute_lookup (hb_font_t *font, const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index); - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_digests[lookup_index]); + return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_accels[lookup_index].digest); } void @@ -731,7 +730,7 @@ hb_ot_layout_position_lookup (hb_font_t *font, const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index); - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_digests[lookup_index]); + return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_accels[lookup_index].digest); } void diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 996e40e8d..91d6e44e5 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -199,7 +199,7 @@ struct arabic_fallback_plan_t hb_mask_t mask_array[ARABIC_NUM_FALLBACK_FEATURES]; OT::SubstLookup *lookup_array[ARABIC_NUM_FALLBACK_FEATURES]; - hb_set_digest_t digest_array[ARABIC_NUM_FALLBACK_FEATURES]; + hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_NUM_FALLBACK_FEATURES]; }; static const arabic_fallback_plan_t arabic_fallback_plan_nil = {}; @@ -214,12 +214,11 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) { - fallback_plan->digest_array[i].init (); fallback_plan->mask_array[i] = plan->map.get_1_mask (arabic_fallback_features[i]); if (fallback_plan->mask_array[i]) { fallback_plan->lookup_array[i] = arabic_fallback_synthesize_lookup (plan, font, i); if (fallback_plan->lookup_array[i]) - fallback_plan->lookup_array[i]->add_coverage (&fallback_plan->digest_array[i]); + fallback_plan->accel_array[i].init (*fallback_plan->lookup_array[i]); } } @@ -234,7 +233,10 @@ arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) if (fallback_plan->lookup_array[i]) + { + fallback_plan->accel_array[i].fini (fallback_plan->lookup_array[i]); free (fallback_plan->lookup_array[i]); + } free (fallback_plan); } @@ -247,7 +249,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) if (fallback_plan->lookup_array[i]) { OT::hb_apply_context_t c (0, font, buffer, fallback_plan->mask_array[i], true/*auto_zwj*/); - fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->digest_array[i]); + fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->accel_array[i].digest); } } From d2c96819de9a7428b65ef0adf794416224221f36 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2013 18:18:24 -0400 Subject: [PATCH 3/9] Move code around --- src/hb-ot-layout.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++ src/hb-ot-map.cc | 43 ------------------------------------- 2 files changed, 52 insertions(+), 43 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 76a6256e4..a944a95fe 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -34,6 +34,8 @@ #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" +#include "hb-ot-map-private.hh" + #include #include @@ -783,3 +785,53 @@ hb_ot_layout_get_size_params (hb_face_t *face, return false; } + + +/* + * Parts of hb-ot-map are implemented here such that they have direct + * access to GSUB/GPOS lookups. + */ + + +inline void hb_ot_map_t::apply (unsigned int table_index, + const hb_ot_shape_plan_t *plan, + hb_font_t *font, + hb_buffer_t *buffer) const +{ + unsigned int i = 0; + + for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { + const stage_map_t *stage = &stages[table_index][stage_index]; + for (; i < stage->last_lookup; i++) + switch (table_index) + { + case 0: + hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, + lookups[table_index][i].mask, + lookups[table_index][i].auto_zwj); + break; + + case 1: + hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, + lookups[table_index][i].mask, + lookups[table_index][i].auto_zwj); + break; + } + + if (stage->pause_func) + { + buffer->clear_output (); + stage->pause_func (plan, font, buffer); + } + } +} + +void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +{ + apply (0, plan, font, buffer); +} + +void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const +{ + apply (1, plan, font, buffer); +} diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index dd26afc8e..43856fa37 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -102,49 +102,6 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value, info->stage[1] = current_stage[1]; } -inline void hb_ot_map_t::apply (unsigned int table_index, - const hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) const -{ - unsigned int i = 0; - - for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { - const stage_map_t *stage = &stages[table_index][stage_index]; - for (; i < stage->last_lookup; i++) - switch (table_index) - { - case 0: - hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - break; - - case 1: - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - break; - } - - if (stage->pause_func) - { - buffer->clear_output (); - stage->pause_func (plan, font, buffer); - } - } -} - -void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const -{ - apply (0, plan, font, buffer); -} - -void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const -{ - apply (1, plan, font, buffer); -} - void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_out) const { From bac1dd6a0ff4d4fae4254506d38ae662b7e9dda7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 2 May 2013 18:52:24 -0400 Subject: [PATCH 4/9] [OTLayout] Refactor a bit more --- src/hb-ot-layout-gsubgpos-private.hh | 10 +-- src/hb-ot-layout-private.hh | 26 +++--- src/hb-ot-layout.cc | 100 ++++++++++----------- src/hb-ot-map-private.hh | 7 +- src/hb-ot-shape-complex-arabic-fallback.hh | 7 +- src/hb-ot-shape-fallback.cc | 3 +- 6 files changed, 78 insertions(+), 75 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 5a5bce334..5169e7877 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -278,14 +278,12 @@ struct hb_apply_context_t hb_apply_context_t (unsigned int table_index_, hb_font_t *font_, - hb_buffer_t *buffer_, - hb_mask_t lookup_mask_, - bool auto_zwj_) : + hb_buffer_t *buffer_) : table_index (table_index_), font (font_), face (font->face), buffer (buffer_), direction (buffer_->props.direction), - lookup_mask (lookup_mask_), - auto_zwj (auto_zwj_), + lookup_mask (1), + auto_zwj (true), recurse_func (NULL), nesting_level_left (MAX_NESTING_LEVEL), lookup_props (0), @@ -293,6 +291,8 @@ struct hb_apply_context_t has_glyph_classes (gdef.has_glyph_classes ()), debug_depth (0) {} + inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; } + inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; } inline void set_recurse_func (recurse_func_t func) { recurse_func = func; } inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; } inline void set_lookup (const Lookup &l) { lookup_props = l.get_props (); } diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index bd01078ee..a9de35690 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -202,12 +202,19 @@ HB_INTERNAL void hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL hb_bool_t -hb_ot_layout_substitute_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask, - hb_bool_t auto_zwj); + +struct hb_ot_layout_lookup_accelerator_t; + +namespace OT { + struct hb_apply_context_t; + struct SubstLookup; +} + +HB_INTERNAL void +hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, + const OT::SubstLookup &lookup, + const hb_ot_layout_lookup_accelerator_t &accel); + /* Should be called after all the substitute_lookup's are done */ HB_INTERNAL void @@ -220,13 +227,6 @@ HB_INTERNAL void hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL 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_bool_t auto_zwj); - /* Should be called after all the position_lookup's are done */ HB_INTERNAL void hb_ot_layout_position_finish (hb_font_t *font, diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index a944a95fe..d1d63e328 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -669,22 +669,6 @@ hb_ot_layout_substitute_start (hb_font_t *font, hb_buffer_t *buffer) OT::GSUB::substitute_start (font, buffer); } -hb_bool_t -hb_ot_layout_substitute_lookup (hb_font_t *font, - hb_buffer_t *buffer, - unsigned int lookup_index, - hb_mask_t mask, - hb_bool_t auto_zwj) -{ - if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gsub_lookup_count)) return false; - - OT::hb_apply_context_t c (0, font, buffer, mask, auto_zwj); - - const OT::SubstLookup& l = hb_ot_layout_from_face (font->face)->gsub->get_lookup (lookup_index); - - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gsub_accels[lookup_index].digest); -} - void hb_ot_layout_substitute_finish (hb_font_t *font, hb_buffer_t *buffer) { @@ -719,22 +703,6 @@ hb_ot_layout_position_start (hb_font_t *font, hb_buffer_t *buffer) OT::GPOS::position_start (font, 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_bool_t auto_zwj) -{ - if (unlikely (lookup_index >= hb_ot_layout_from_face (font->face)->gpos_lookup_count)) return false; - - OT::hb_apply_context_t c (1, font, buffer, mask, auto_zwj); - - const OT::PosLookup& l = hb_ot_layout_from_face (font->face)->gpos->get_lookup (lookup_index); - - return l.apply_string (&c, &hb_ot_layout_from_face (font->face)->gpos_accels[lookup_index].digest); -} - void hb_ot_layout_position_finish (hb_font_t *font, hb_buffer_t *buffer) { @@ -788,35 +756,57 @@ hb_ot_layout_get_size_params (hb_face_t *face, /* - * Parts of hb-ot-map are implemented here such that they have direct + * Parts of different types are implemented here such that they have direct * access to GSUB/GPOS lookups. */ -inline void hb_ot_map_t::apply (unsigned int table_index, +struct GSUBProxy +{ + static const unsigned int table_index = 0; + typedef OT::SubstLookup Lookup; + + GSUBProxy (hb_face_t *face) : + table (*hb_ot_layout_from_face (face)->gsub), + accels (hb_ot_layout_from_face (face)->gsub_accels) {} + + const OT::GSUB &table; + const hb_ot_layout_lookup_accelerator_t *accels; +}; + +struct GPOSProxy +{ + static const unsigned int table_index = 1; + typedef OT::PosLookup Lookup; + + GPOSProxy (hb_face_t *face) : + table (*hb_ot_layout_from_face (face)->gpos), + accels (hb_ot_layout_from_face (face)->gpos_accels) {} + + const OT::GPOS &table; + const hb_ot_layout_lookup_accelerator_t *accels; +}; + + +template +inline void hb_ot_map_t::apply (const Proxy &proxy, const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { + const unsigned int table_index = proxy.table_index; unsigned int i = 0; + OT::hb_apply_context_t c (table_index, font, buffer); for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { const stage_map_t *stage = &stages[table_index][stage_index]; for (; i < stage->last_lookup; i++) - switch (table_index) - { - case 0: - hb_ot_layout_substitute_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - break; - - case 1: - hb_ot_layout_position_lookup (font, buffer, lookups[table_index][i].index, - lookups[table_index][i].mask, - lookups[table_index][i].auto_zwj); - break; - } + { + unsigned int lookup_index = lookups[table_index][i].index; + c.set_lookup_mask (lookups[table_index][i].mask); + c.set_auto_zwj (lookups[table_index][i].auto_zwj); + proxy.table.get_lookup (lookup_index).apply_string (&c, &proxy.accels[lookup_index].digest); + } if (stage->pause_func) { @@ -828,10 +818,20 @@ inline void hb_ot_map_t::apply (unsigned int table_index, void hb_ot_map_t::substitute (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { - apply (0, plan, font, buffer); + GSUBProxy proxy (font->face); + apply (proxy, plan, font, buffer); } void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const { - apply (1, plan, font, buffer); + GPOSProxy proxy (font->face); + apply (proxy, plan, font, buffer); +} + +HB_INTERNAL void +hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, + const OT::SubstLookup &lookup, + const hb_ot_layout_lookup_accelerator_t &accel) +{ + lookup.apply_string (c, &accel.digest); } diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 5ed54a6ca..0e718a6f1 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -118,10 +118,9 @@ struct hb_ot_map_t } HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const; - HB_INTERNAL inline void apply (unsigned int table_index, - const struct hb_ot_shape_plan_t *plan, - hb_font_t *font, - hb_buffer_t *buffer) const; + template + HB_INTERNAL inline void apply (const Proxy &proxy, + const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void substitute (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; HB_INTERNAL void position (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const; diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 91d6e44e5..6b2b87e3f 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -246,10 +246,13 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan, hb_font_t *font, hb_buffer_t *buffer) { + OT::hb_apply_context_t c (0, font, buffer); for (unsigned int i = 0; i < ARABIC_NUM_FALLBACK_FEATURES; i++) if (fallback_plan->lookup_array[i]) { - OT::hb_apply_context_t c (0, font, buffer, fallback_plan->mask_array[i], true/*auto_zwj*/); - fallback_plan->lookup_array[i]->apply_string (&c, &fallback_plan->accel_array[i].digest); + c.set_lookup_mask (fallback_plan->mask_array[i]); + hb_ot_layout_substitute_lookup (&c, + *fallback_plan->lookup_array[i], + fallback_plan->accel_array[i]); } } diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 334182544..284d030d5 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -420,7 +420,8 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, hb_mask_t kern_mask = plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ? HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n')); - OT::hb_apply_context_t c (1, font, buffer, kern_mask, true/*auto_zwj*/); + OT::hb_apply_context_t c (1, font, buffer); + c.set_lookup_mask (kern_mask); c.set_lookup_props (OT::LookupFlag::IgnoreMarks); for (buffer->idx = 0; buffer->idx < count;) From 2e0c44f4bedd3e24c731c0e9e23358e9a4891a35 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2013 16:42:05 -0400 Subject: [PATCH 5/9] [OTLayout] Add is_inplace() method to GSUB --- src/hb-ot-layout-gpos-table.hh | 8 +- src/hb-ot-layout-gsub-table.hh | 58 +++++++++- src/hb-ot-layout-gsubgpos-private.hh | 158 +++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 56b3a4f61..a9933d14b 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -1429,6 +1429,12 @@ struct PosLookup : Lookup inline const PosLookupSubTable& get_subtable (unsigned int i) const { return this+CastR > (subTable)[i]; } + inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 3b6635bf9..fc37cd93d 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1,6 +1,6 @@ /* * Copyright © 2007,2008,2009,2010 Red Hat, Inc. - * Copyright © 2010,2012 Google, Inc. + * Copyright © 2010,2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -37,6 +37,12 @@ namespace OT { struct SingleSubstFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -115,6 +121,12 @@ struct SingleSubstFormat1 struct SingleSubstFormat2 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -251,6 +263,13 @@ struct SingleSubst struct Sequence { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + /* For len==0 we don't do anything, so it's harmless. */ + return TRACE_RETURN (substitute.len <= 1); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -315,6 +334,18 @@ struct Sequence struct MultipleSubstFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + /* Some tools generate MultipleSubst with each substitute having length 1! + * So, check them. */ + unsigned int count = sequence.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+sequence[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -440,6 +471,12 @@ typedef ArrayOf AlternateSet; /* Array of alternate GlyphIDs--in struct AlternateSubstFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -760,6 +797,12 @@ struct LigatureSet struct LigatureSubstFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (false); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -908,6 +951,12 @@ struct ExtensionSubst : Extension struct ReverseChainSingleSubstFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1145,6 +1194,13 @@ struct SubstLookup : Lookup return lookup_type_is_reverse (type); } + inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + c->set_recurse_func (dispatch_recurse_func); + return TRACE_RETURN (dispatch (c)); + } + inline hb_closure_context_t::return_t closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index 5169e7877..9fc638b75 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -44,6 +44,55 @@ namespace OT { ""); + +#ifndef HB_DEBUG_IS_INPLACE +#define HB_DEBUG_IS_INPLACE (HB_DEBUG+0) +#endif + +#define TRACE_IS_INPLACE(this) \ + hb_auto_trace_t trace \ + (&c->debug_depth, c->get_name (), this, HB_FUNC, \ + ""); + +struct hb_is_inplace_context_t +{ + inline const char *get_name (void) { return "IS_INPLACE"; } + static const unsigned int max_debug_depth = HB_DEBUG_IS_INPLACE; + typedef bool return_t; + typedef return_t (*recurse_func_t) (hb_is_inplace_context_t *c, unsigned int lookup_index); + template + inline return_t dispatch (const T &obj) { return obj.is_inplace (this); } + static return_t default_return_value (void) { return true; } + bool stop_sublookup_iteration (return_t r) const { return !r; } + + return_t recurse (unsigned int lookup_index) + { + if (unlikely (nesting_level_left == 0 || !recurse_func)) + return default_return_value (); + + nesting_level_left--; + bool ret = recurse_func (this, lookup_index); + nesting_level_left++; + return ret; + } + + hb_face_t *face; + recurse_func_t recurse_func; + unsigned int nesting_level_left; + unsigned int debug_depth; + + hb_is_inplace_context_t (hb_face_t *face_, + unsigned int nesting_level_left_ = MAX_NESTING_LEVEL) : + face (face_), + recurse_func (NULL), + nesting_level_left (nesting_level_left_), + debug_depth (0) {} + + void set_recurse_func (recurse_func_t func) { recurse_func = func; } +}; + + + #ifndef HB_DEBUG_CLOSURE #define HB_DEBUG_CLOSURE (HB_DEBUG+0) #endif @@ -1102,6 +1151,17 @@ static inline bool context_apply_lookup (hb_apply_context_t *c, struct Rule { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const LookupRecord *lookupRecord = &StructAtOffset (input, input[0].static_size * (inputCount ? inputCount - 1 : 0)); + unsigned int count = lookupCount; + for (unsigned int i = 0; i < count; i++) + if (!c->recurse (lookupRecord[i].lookupListIndex)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); @@ -1161,6 +1221,16 @@ struct Rule struct RuleSet { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int num_rules = rule.len; + for (unsigned int i = 0; i < num_rules; i++) + if (!(this+rule[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); @@ -1217,6 +1287,16 @@ struct RuleSet struct ContextFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int count = ruleSet.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+ruleSet[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1303,6 +1383,16 @@ struct ContextFormat1 struct ContextFormat2 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int count = ruleSet.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+ruleSet[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1398,6 +1488,17 @@ struct ContextFormat2 struct ContextFormat3 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const LookupRecord *lookupRecord = &StructAtOffset (coverage, coverage[0].static_size * glyphCount); + unsigned int count = lookupCount; + for (unsigned int i = 0; i < count; i++) + if (!c->recurse (lookupRecord[i].lookupListIndex)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1639,6 +1740,19 @@ static inline bool chain_context_apply_lookup (hb_apply_context_t *c, struct ChainRule { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const HeadlessArrayOf &input = StructAfter > (backtrack); + const ArrayOf &lookahead = StructAfter > (input); + const ArrayOf &lookup = StructAfter > (lookahead); + unsigned int count = lookup.len; + for (unsigned int i = 0; i < count; i++) + if (!c->recurse (lookup.array[i].lookupListIndex)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); @@ -1724,6 +1838,16 @@ struct ChainRule struct ChainRuleSet { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int num_rules = rule.len; + for (unsigned int i = 0; i < num_rules; i++) + if (!(this+rule[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const { TRACE_CLOSURE (this); @@ -1777,6 +1901,16 @@ struct ChainRuleSet struct ChainContextFormat1 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int count = ruleSet.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+ruleSet[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1860,6 +1994,16 @@ struct ChainContextFormat1 struct ChainContextFormat2 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + unsigned int count = ruleSet.len; + for (unsigned int i = 0; i < count; i++) + if (!(this+ruleSet[i]).is_inplace (c)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); @@ -1984,6 +2128,20 @@ struct ChainContextFormat2 struct ChainContextFormat3 { + inline bool is_inplace (hb_is_inplace_context_t *c) const + { + TRACE_IS_INPLACE (this); + const OffsetArrayOf &input = StructAfter > (backtrack); + const OffsetArrayOf &lookahead = StructAfter > (input); + const ArrayOf &lookup = StructAfter > (lookahead); + + unsigned int count = lookup.len; + for (unsigned int i = 0; i < count; i++) + if (!c->recurse (lookup.array[i].lookupListIndex)) + return TRACE_RETURN (false); + return TRACE_RETURN (true); + } + inline void closure (hb_closure_context_t *c) const { TRACE_CLOSURE (this); From 780cd930a974165d76dbf7a87701d11b7f15db06 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 3 May 2013 17:33:16 -0400 Subject: [PATCH 6/9] [OTLayout] Minor --- src/hb-ot-layout-gpos-table.hh | 2 +- src/hb-ot-layout-gsub-table.hh | 2 +- src/hb-ot-layout.cc | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index a9933d14b..7e5efa27d 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1435,7 +1435,7 @@ struct PosLookup : Lookup return TRACE_RETURN (true); } - inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const + inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); c->set_recurse_func (NULL); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index fc37cd93d..123b17cfe 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1208,7 +1208,7 @@ struct SubstLookup : Lookup return TRACE_RETURN (dispatch (c)); } - inline hb_collect_glyphs_context_t::return_t collect_glyphs_lookup (hb_collect_glyphs_context_t *c) const + inline hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const { TRACE_COLLECT_GLYPHS (this); c->set_recurse_func (dispatch_recurse_func); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index d1d63e328..a70f84c96 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -614,13 +614,13 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, case HB_OT_TAG_GSUB: { const OT::SubstLookup& l = hb_ot_layout_from_face (face)->gsub->get_lookup (lookup_index); - l.collect_glyphs_lookup (&c); + l.collect_glyphs (&c); return; } case HB_OT_TAG_GPOS: { const OT::PosLookup& l = hb_ot_layout_from_face (face)->gpos->get_lookup (lookup_index); - l.collect_glyphs_lookup (&c); + l.collect_glyphs (&c); return; } } From e015b8f2187d1102b9c34d1a63504e7b05ee20ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 3 May 2013 17:34:29 -0400 Subject: [PATCH 7/9] [OTLayout] Minor --- src/hb-ot-layout-gpos-table.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index 7e5efa27d..e47af0799 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1429,6 +1429,11 @@ struct PosLookup : Lookup inline const PosLookupSubTable& get_subtable (unsigned int i) const { return this+CastR > (subTable)[i]; } + inline bool is_reverse (void) const + { + return false; + } + inline hb_is_inplace_context_t::return_t is_inplace (hb_is_inplace_context_t *c) const { TRACE_IS_INPLACE (this); From 45f3d980c9503bd94e64f6e3f67f97688347d00c Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 3 May 2013 17:49:44 -0400 Subject: [PATCH 8/9] [OTLayout] Merge / templateize apply_string() --- src/hb-ot-layout-gpos-table.hh | 25 ------------ src/hb-ot-layout-gsub-table.hh | 48 ----------------------- src/hb-ot-layout.cc | 72 ++++++++++++++++++++++++++++++++-- 3 files changed, 69 insertions(+), 76 deletions(-) diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh index e47af0799..2cf90b7b5 100644 --- a/src/hb-ot-layout-gpos-table.hh +++ b/src/hb-ot-layout-gpos-table.hh @@ -1472,31 +1472,6 @@ struct PosLookup : Lookup static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); - inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const - { - bool ret = false; - - if (unlikely (!c->buffer->len || !c->lookup_mask)) - return false; - - c->set_recurse_func (apply_recurse_func); - c->set_lookup (*this); - - c->buffer->idx = 0; - - while (c->buffer->idx < c->buffer->len) - { - if (digest->may_have (c->buffer->cur().codepoint) && - (c->buffer->cur().mask & c->lookup_mask) && - apply_once (c)) - ret = true; - else - c->buffer->idx++; - } - - return ret; - } - template static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index); diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 123b17cfe..6ab1a2b92 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -1247,54 +1247,6 @@ struct SubstLookup : Lookup } static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index); - inline bool apply_string (hb_apply_context_t *c, const hb_set_digest_t *digest) const - { - bool ret = false; - - if (unlikely (!c->buffer->len || !c->lookup_mask)) - return false; - - c->set_recurse_func (apply_recurse_func); - c->set_lookup (*this); - - if (likely (!is_reverse ())) - { - /* in/out forward substitution */ - c->buffer->clear_output (); - c->buffer->idx = 0; - - while (c->buffer->idx < c->buffer->len) - { - if (digest->may_have (c->buffer->cur().codepoint) && - (c->buffer->cur().mask & c->lookup_mask) && - apply_once (c)) - ret = true; - else - c->buffer->next_glyph (); - } - if (ret) - c->buffer->swap_buffers (); - } - else - { - /* in-place backward substitution */ - c->buffer->remove_output (); - c->buffer->idx = c->buffer->len - 1; - do - { - if (digest->may_have (c->buffer->cur().codepoint) && - (c->buffer->cur().mask & c->lookup_mask) && - apply_once (c)) - ret = true; - else - c->buffer->idx--; - - } - while ((int) c->buffer->idx >= 0); - } - - return ret; - } inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c, unsigned int i) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index a70f84c96..145cf8f86 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2,7 +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. + * Copyright © 2012,2013 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -788,6 +788,69 @@ struct GPOSProxy }; +template +static inline bool apply_once (OT::hb_apply_context_t *c, + const Lookup &lookup) +{ + if (!c->check_glyph_property (&c->buffer->cur(), c->lookup_props)) + return false; + return lookup.dispatch (c); +} + +template +static inline bool +apply_string (OT::hb_apply_context_t *c, + const typename Proxy::Lookup &lookup, + const hb_ot_layout_lookup_accelerator_t &accel) +{ + bool ret = false; + + if (unlikely (!c->buffer->len || !c->lookup_mask)) + return false; + + c->set_lookup (lookup); + + if (likely (!lookup.is_reverse ())) + { + /* in/out forward substitution/positioning */ + if (Proxy::table_index == 0) + c->buffer->clear_output (); + c->buffer->idx = 0; + + while (c->buffer->idx < c->buffer->len) + { + if (accel.digest.may_have (c->buffer->cur().codepoint) && + (c->buffer->cur().mask & c->lookup_mask) && + apply_once (c, lookup)) + ret = true; + else + c->buffer->next_glyph (); + } + if (ret && Proxy::table_index == 0) + c->buffer->swap_buffers (); + } + else + { + /* in-place backward substitution/positioning */ + if (Proxy::table_index == 0) + c->buffer->remove_output (); + c->buffer->idx = c->buffer->len - 1; + do + { + if (accel.digest.may_have (c->buffer->cur().codepoint) && + (c->buffer->cur().mask & c->lookup_mask) && + apply_once (c, lookup)) + ret = true; + else + c->buffer->idx--; + + } + while ((int) c->buffer->idx >= 0); + } + + return ret; +} + template inline void hb_ot_map_t::apply (const Proxy &proxy, const hb_ot_shape_plan_t *plan, @@ -797,6 +860,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, const unsigned int table_index = proxy.table_index; unsigned int i = 0; OT::hb_apply_context_t c (table_index, font, buffer); + c.set_recurse_func (Proxy::Lookup::apply_recurse_func); for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) { const stage_map_t *stage = &stages[table_index][stage_index]; @@ -805,7 +869,9 @@ inline void hb_ot_map_t::apply (const Proxy &proxy, unsigned int lookup_index = lookups[table_index][i].index; c.set_lookup_mask (lookups[table_index][i].mask); c.set_auto_zwj (lookups[table_index][i].auto_zwj); - proxy.table.get_lookup (lookup_index).apply_string (&c, &proxy.accels[lookup_index].digest); + apply_string (&c, + proxy.table.get_lookup (lookup_index), + proxy.accels[lookup_index]); } if (stage->pause_func) @@ -833,5 +899,5 @@ hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c, const OT::SubstLookup &lookup, const hb_ot_layout_lookup_accelerator_t &accel) { - lookup.apply_string (c, &accel.digest); + apply_string (c, lookup, accel); } From 9d9e72e94e7914f82ce62a304e7242f79c13edaf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 3 May 2013 18:10:10 -0400 Subject: [PATCH 9/9] [OTLayout] Use is_inplace() when flipping buffers --- src/hb-ot-layout.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 145cf8f86..355f51c92 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -804,6 +804,8 @@ apply_string (OT::hb_apply_context_t *c, const hb_ot_layout_lookup_accelerator_t &accel) { bool ret = false; + OT::hb_is_inplace_context_t inplace_c (c->face); + bool inplace = lookup.is_inplace (&inplace_c); if (unlikely (!c->buffer->len || !c->lookup_mask)) return false; @@ -826,8 +828,13 @@ apply_string (OT::hb_apply_context_t *c, else c->buffer->next_glyph (); } - if (ret && Proxy::table_index == 0) + if (ret) + { + if (!inplace) c->buffer->swap_buffers (); + else + assert (!c->buffer->has_separate_output ()); + } } else {