src/hb-ot-map-private.hh | 2 + src/hb-ot-shape.cc | 62 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-)
New commits: commit 3aeee519f0b82df5263974945ae852badc4dbded Author: Behdad Esfahbod <[email protected]> Date: Sun Dec 22 16:17:54 2013 -0500 Bug 72698 - Automatically support frac / numr / dnom When seeing U+2044 FRACTION SLASH in the text, find decimal digits (Unicode General Category Decimal_Number) around it, and mark the pre-slash digits with 'numr' feature, the post-slash digits with 'dnom' feature, and the whole sequence with 'frac' feature. This beautifully renders fractions with major Windows fonts, and any other font that implements those features (numr/dnom is enough for most fonts.) Not the fastest way to do this, but good enough for a start. diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 5390765..1ef216c 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -88,6 +88,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, break; } + map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE); + map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE); + map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE); + if (planner->shaper->collect_features) planner->shaper->collect_features (planner); @@ -306,6 +310,51 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) } static inline void +hb_ot_shape_setup_masks_fraction (hb_ot_shape_context_t *c) +{ + hb_buffer_t *buffer = c->buffer; + bool initialized = false; + hb_mask_t frac_mask = 0, numr_mask = 0, dnom_mask = 0; + + /* TODO look in pre/post context text also. */ + unsigned int count = buffer->len; + hb_glyph_info_t *info = buffer->info; + for (unsigned int i = 0; i < count; i++) + { + if (info[i].codepoint == 0x2044) /* FRACTION SLASH */ + { + if (!initialized) + { + initialized = true; + + frac_mask = c->plan->map.get_1_mask (HB_TAG ('f','r','a','c')); + numr_mask = c->plan->map.get_1_mask (HB_TAG ('n','u','m','r')); + dnom_mask = c->plan->map.get_1_mask (HB_TAG ('d','n','o','m')); + + if (!(frac_mask | numr_mask | dnom_mask)) + return; + } + + unsigned int start = i, end = i + 1; + while (start && + _hb_glyph_info_get_general_category (&info[start - 1]) == + HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + start--; + while (end < count && + _hb_glyph_info_get_general_category (&info[end]) == + HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER) + end++; + + buffer->set_masks (frac_mask, frac_mask, start, end); + buffer->set_masks (numr_mask, numr_mask, start, i); + buffer->set_masks (dnom_mask, dnom_mask, i + 1, end); + + i = end - 1; + } + } +} + +static inline void hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; @@ -321,6 +370,8 @@ hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; + hb_ot_shape_setup_masks_fraction (c); + if (c->plan->shaper->setup_masks) c->plan->shaper->setup_masks (c->plan, buffer, c->font); commit 014f369ec98fdbb3e7a2ef68aea2c4e017e7b680 Author: Behdad Esfahbod <[email protected]> Date: Sun Dec 22 16:15:30 2013 -0500 Add XXX note diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh index 0e718a6..1b4f029 100644 --- a/src/hb-ot-map-private.hh +++ b/src/hb-ot-map-private.hh @@ -88,6 +88,8 @@ struct hb_ot_map_t return map ? map->needs_fallback : false; } + /* XXX get_1_mask is actually unsafe if feature has more than + * one bit. */ inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const { const feature_map_t *map = features.bsearch (&feature_tag); return map ? map->_1_mask : 0; commit 739325178aba00ea5526c6a54ce588a79e5d45e2 Author: Behdad Esfahbod <[email protected]> Date: Sat Dec 21 00:18:18 2013 -0500 Initialize masks before mirroring We were throwing away the rtlm feature mask set during mirroring... diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index 63c36f9..5390765 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -306,13 +306,20 @@ hb_ot_mirror_chars (hb_ot_shape_context_t *c) } static inline void -hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +hb_ot_shape_initialize_masks (hb_ot_shape_context_t *c) { hb_ot_map_t *map = &c->plan->map; hb_buffer_t *buffer = c->buffer; hb_mask_t global_mask = map->get_global_mask (); buffer->reset_masks (global_mask); +} + +static inline void +hb_ot_shape_setup_masks (hb_ot_shape_context_t *c) +{ + hb_ot_map_t *map = &c->plan->map; + hb_buffer_t *buffer = c->buffer; if (c->plan->shaper->setup_masks) c->plan->shaper->setup_masks (c->plan, buffer, c->font); @@ -358,6 +365,8 @@ hb_ot_substitute_default (hb_ot_shape_context_t *c) if (c->plan->shaper->preprocess_text) c->plan->shaper->preprocess_text (c->plan, buffer, c->font); + hb_ot_shape_initialize_masks (c); + hb_ot_mirror_chars (c); HB_BUFFER_ALLOCATE_VAR (buffer, glyph_index); _______________________________________________ HarfBuzz mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/harfbuzz
