[HarfBuzz] harfbuzz: Branch 'master' - 3 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Sun Dec 22 13:21:45 PST 2013


 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 <behdad at behdad.org>
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 <behdad at behdad.org>
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 <behdad at behdad.org>
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);


More information about the HarfBuzz mailing list