diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc index e0db41cbf..e1a2791c5 100644 --- a/src/hb-ot-shape-complex-arabic.cc +++ b/src/hb-ot-shape-complex-arabic.cc @@ -274,12 +274,8 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer) } static void -setup_masks_arabic (const hb_ot_shape_plan_t *plan, - hb_buffer_t *buffer, - hb_font_t *font) +arabic_joining (hb_buffer_t *buffer) { - const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; - unsigned int count = buffer->len; unsigned int prev = 0, state = 0; @@ -305,14 +301,37 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan, state = entry->next_state; } - if (likely (!arabic_plan->do_fallback)) { - /* Has OpenType tables */ + HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); +} + +static void +preprocess_text_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; + + if (unlikely (arabic_plan->do_fallback)) + { + arabic_joining (buffer); + arabic_fallback_shape (font, buffer); + } +} + +static void +setup_masks_arabic (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font) +{ + const arabic_shape_plan_t *arabic_plan = (const arabic_shape_plan_t *) plan->data; + + if (likely (!arabic_plan->do_fallback)) + { + arabic_joining (buffer); + unsigned int count = buffer->len; for (unsigned int i = 0; i < count; i++) buffer->info[i].mask |= arabic_plan->mask_array[buffer->info[i].arabic_shaping_action()]; - } else - arabic_fallback_shape (font, buffer); - - HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action); + } } const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = @@ -322,6 +341,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic = NULL, /* override_features */ data_create_arabic, data_destroy_arabic, + preprocess_text_arabic, NULL, /* normalization_preference */ setup_masks_arabic, true, /* zero_width_attached_marks */ diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 4f9a5af9c..6fbd5c812 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1134,6 +1134,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic = override_features_indic, data_create_indic, data_destroy_indic, + NULL, /* preprocess_text */ NULL, /* normalization_preference */ setup_masks_indic, false, /* zero_width_attached_marks */ diff --git a/src/hb-ot-shape-complex-misc.cc b/src/hb-ot-shape-complex-misc.cc index 4f1dd5b2d..13bc22b4d 100644 --- a/src/hb-ot-shape-complex-misc.cc +++ b/src/hb-ot-shape-complex-misc.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2010 Google, Inc. + * Copyright © 2010,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * @@ -90,6 +90,7 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = NULL, /* override_features */ NULL, /* data_create */ NULL, /* data_destroy */ + NULL, /* preprocess_text */ normalization_preference_default, NULL, /* setup_masks */ true, /* zero_width_attached_marks */ @@ -99,9 +100,9 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = /* Thai / Lao shaper */ static void -setup_masks_thai (const hb_ot_shape_plan_t *plan HB_UNUSED, - hb_buffer_t *buffer, - hb_font_t *font HB_UNUSED) +preprocess_text_thai (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + hb_font_t *font HB_UNUSED) { /* The following is NOT specified in the MS OT Thai spec, however, it seems * to be what Uniscribe and other engines implement. According to Eric Muller: @@ -200,7 +201,8 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai = NULL, /* override_features */ NULL, /* data_create */ NULL, /* data_destroy */ + preprocess_text_thai, NULL, /* normalization_preference */ - setup_masks_thai, + NULL, /* setup_masks */ true, /* zero_width_attached_marks */ }; diff --git a/src/hb-ot-shape-complex-private.hh b/src/hb-ot-shape-complex-private.hh index efff3259a..e84c49016 100644 --- a/src/hb-ot-shape-complex-private.hh +++ b/src/hb-ot-shape-complex-private.hh @@ -56,7 +56,6 @@ struct hb_ot_complex_shaper_t /* collect_features() * Called during shape_plan(). * Shapers should use plan->map to add their features and callbacks. - * May be NULL. */ void (*collect_features) (hb_ot_shape_planner_t *plan); @@ -64,7 +63,6 @@ struct hb_ot_complex_shaper_t * Called during shape_plan(). * Shapers should use plan->map to override features and add callbacks after * common features are added. - * May be NULL. */ void (*override_features) (hb_ot_shape_planner_t *plan); @@ -73,7 +71,7 @@ struct hb_ot_complex_shaper_t * Called at the end of shape_plan(). * Whatever shapers return will be accessible through plan->data later. * If NULL is returned, means a plan failure. - * May be NULL. */ + */ void *(*data_create) (const hb_ot_shape_plan_t *plan); /* data_destroy() @@ -83,6 +81,16 @@ struct hb_ot_complex_shaper_t * May be NULL. */ void (*data_destroy) (void *data); + + /* preprocess_text() + * Called during shape(). + * Shapers can use to modify text before shaping starts. + */ + void (*preprocess_text) (const hb_ot_shape_plan_t *plan, + hb_buffer_t *buffer, + hb_font_t *font); + + /* normalization_preference() * Called during shape(). */ @@ -92,6 +100,7 @@ struct hb_ot_complex_shaper_t /* setup_masks() * Called during shape(). * Shapers should use map to get feature masks and set on buffer. + * Shapers may NOT modify characters. */ void (*setup_masks) (const hb_ot_shape_plan_t *plan, hb_buffer_t *buffer, diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 823ecedac..29076cf4d 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -319,6 +319,9 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer) static inline void hb_ot_substitute_default (hb_ot_shape_context_t *c) { + if (c->plan->shaper->preprocess_text) + c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font); + hb_ot_mirror_chars (c); HB_BUFFER_ALLOCATE_VAR (c->buffer, glyph_index);