[HarfBuzz] harfbuzz-ng: Branch 'master' - 2 commits

Behdad Esfahbod behdad at kemper.freedesktop.org
Fri May 21 09:38:06 PDT 2010


 src/hb-buffer-private.hh         |   16 ++++++++++
 src/hb-buffer.cc                 |   36 +++++++++++++++++++++++
 src/hb-ot-layout-gsub-private.hh |    1 
 src/hb-ot-shape.cc               |   60 ++++++++++++++++-----------------------
 4 files changed, 79 insertions(+), 34 deletions(-)

New commits:
commit 1ce7b87c4d8d1ab3ec1d5198351d71b7199f7c64
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri May 21 17:31:45 2010 +0100

    Cleanup bitmask allocation

diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index d897627..d05322b 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -94,6 +94,15 @@ HB_INTERNAL void
 _hb_buffer_next_glyph (hb_buffer_t *buffer);
 
 
+HB_INTERNAL void
+_hb_buffer_clear_masks (hb_buffer_t *buffer);
+
+HB_INTERNAL void
+_hb_buffer_or_masks (hb_buffer_t *buffer,
+		     hb_mask_t    mask,
+		     unsigned int cluster_start,
+		     unsigned int cluster_end);
+
 
 struct _hb_buffer_t {
   hb_reference_count_t ref_count;
@@ -147,6 +156,13 @@ struct _hb_buffer_t {
 				unsigned short ligID = 0xFFFF)
   { _hb_buffer_add_output_glyph (this, glyph_index, component, ligID); }
   inline void replace_glyph (hb_codepoint_t glyph_index) { add_output_glyph (glyph_index); }
+
+  inline void clear_masks (void) { _hb_buffer_clear_masks (this); }
+  inline void or_masks (hb_mask_t    mask,
+			unsigned int cluster_start,
+			unsigned int cluster_end)
+  { _hb_buffer_or_masks (this, mask, cluster_start, cluster_end); }
+
 };
 
 
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 0b77919..c20de77 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -457,6 +457,42 @@ _hb_buffer_next_glyph (hb_buffer_t *buffer)
   buffer->i++;
 }
 
+void
+_hb_buffer_clear_masks (hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    buffer->info[i].mask = 1;
+}
+
+void
+_hb_buffer_or_masks (hb_buffer_t *buffer,
+		     hb_mask_t    mask,
+		     unsigned int cluster_start,
+		     unsigned int cluster_end)
+{
+  if (cluster_start == 0 && cluster_end == (unsigned int)-1) {
+    unsigned int count = buffer->len;
+    for (unsigned int i = 0; i < count; i++)
+      buffer->info[i].mask |= mask;
+    return;
+  }
+
+  /* Binary search to find the start position and go from there. */
+  unsigned int min = 0, max = buffer->len;
+  while (min < max)
+  {
+    unsigned int mid = min + ((max - min) / 2);
+    if (buffer->info[mid].cluster < cluster_start)
+      min = mid + 1;
+    else
+      max = mid;
+  }
+  unsigned int count = buffer->len;
+  for (unsigned int i = min; i < count && buffer->info[i].cluster < cluster_end; i++)
+    buffer->info[i].mask |= mask;
+}
+
 
 /* Public API again */
 
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3d8966c..411087b 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -117,54 +117,46 @@ setup_lookups (hb_face_t    *face,
   }
 
   /* Clear buffer masks. */
-  unsigned int count = buffer->len;
-  for (unsigned int i = 0; i < count; i++)
-    buffer->info[i].mask = 1;
+  buffer->clear_masks ();
 
-  unsigned int last_bit_used = 1;
-  unsigned int global_values = 0;
+  unsigned int next_bit = 1;
+  hb_mask_t global_mask = 0;
   for (i = 0; i < num_features; i++)
   {
+    hb_feature_t *feature = &features[i];
     if (!hb_ot_layout_language_find_feature (face, table_tag, script_index, language_index,
-					     features[i].tag,
+					     feature->tag,
 					     &feature_index))
       continue;
 
-    unsigned int bits_needed = _hb_bit_storage (features[i].value);
-    if (!bits_needed)
+    if (feature->value == 1 && feature->start == 0 && feature->end == (unsigned int) -1) {
+      add_feature (face, table_tag, feature_index, 1, lookups, num_lookups, room_lookups);
       continue;
-    unsigned int mask = (1 << (last_bit_used + bits_needed)) - (1 << last_bit_used);
-    unsigned int value = features[i].value << last_bit_used;
-    last_bit_used += bits_needed;
+    }
+
+    /* Allocate bits for the features */
+
+    unsigned int bits_needed = _hb_bit_storage (feature->value);
+    if (!bits_needed)
+      continue; /* Feature disabled */
+
+    if (next_bit + bits_needed > 8 * sizeof (hb_mask_t))
+      continue; /* Oh well... */
+
+    unsigned int mask = (1 << (next_bit + bits_needed)) - (1 << next_bit);
+    unsigned int value = feature->value << next_bit;
+    next_bit += bits_needed;
 
     add_feature (face, table_tag, feature_index, mask, lookups, num_lookups, room_lookups);
 
-    if (features[i].start == 0 && features[i].end == (unsigned int)-1)
-      global_values |= value;
+    if (feature->start == 0 && feature->end == (unsigned int) -1)
+      global_mask |= value;
     else
-    {
-      unsigned int start = features[i].start, end = features[i].end;
-      unsigned int a = 0, b = buffer->len;
-      while (a < b)
-      {
-        unsigned int h = a + ((b - a) / 2);
-        if (buffer->info[h].cluster < start)
-          a = h + 1;
-        else
-          b = h;
-      }
-      unsigned int count = buffer->len;
-      for (unsigned int j = a; j < count && buffer->info[j].cluster < end; j++)
-        buffer->info[j].mask |= value;
-    }
+      buffer->or_masks (mask, feature->start, feature->end);
   }
 
-  if (global_values)
-  {
-    unsigned int count = buffer->len;
-    for (unsigned int j = 0; j < count; j++)
-      buffer->info[j].mask |= global_values;
-  }
+  if (global_mask)
+    buffer->or_masks (global_mask, 0, (unsigned int) -1);
 
   qsort (lookups, *num_lookups, sizeof (lookups[0]), cmp_lookups);
 
commit dd22a8f7bfd424a69286e90f79d2a23af6e89ec1
Author: Behdad Esfahbod <behdad at behdad.org>
Date:   Fri May 21 16:43:17 2010 +0100

    Add note

diff --git a/src/hb-ot-layout-gsub-private.hh b/src/hb-ot-layout-gsub-private.hh
index d64c095..9af5b63 100644
--- a/src/hb-ot-layout-gsub-private.hh
+++ b/src/hb-ot-layout-gsub-private.hh
@@ -286,6 +286,7 @@ struct AlternateSubstFormat1
     if (unlikely (!alt_set.len))
       return false;
 
+    /* Note: This breaks badly if two features enabled this lookup together. */
     unsigned int shift = _hb_ctz (lookup_mask);
     unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
 



More information about the HarfBuzz mailing list