[buffer] Save pre/post textual context
authorBehdad Esfahbod <behdad@behdad.org>
Tue, 25 Sep 2012 21:44:53 +0000 (17:44 -0400)
committerBehdad Esfahbod <behdad@behdad.org>
Wed, 26 Sep 2012 01:32:21 +0000 (21:32 -0400)
To be used for a variety of purposes.  We save up to five characters
in each direction.  No public API changes, everything is taken care
of already.  All clients need to do is to call hb_buffer_add_utf* with
the full text + segment info (or at least some context) instead of
just passing in the segment.

Various operations (hb_buffer_reset, hb_buffer_set_length,
hb_buffer_add*) automatically reset the relevant contexts.

src/hb-buffer-private.hh
src/hb-buffer.cc
src/hb-buffer.h

index f5d64f3..67a2752 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 1998-2004  David Turner and Werner Lemberg
  * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
- * Copyright © 2011  Google, Inc.
+ * Copyright © 2011,2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -117,9 +117,18 @@ struct hb_buffer_t {
   inline hb_glyph_info_t prev (void) const { return info[out_len - 1]; }
 
   unsigned int serial;
+
+  /* These reflect current allocations of the bytes in glyph_info_t's var1 and var2. */
   uint8_t allocated_var_bytes[8];
   const char *allocated_var_owner[8];
 
+  /* Text before / after the main buffer contents.
+   * Always in Unicode, and ordered outward.
+   * Index 0 is for "pre-context", 1 for "post-context". */
+  static const unsigned int CONTEXT_LENGTH = 5;
+  hb_codepoint_t context[2][CONTEXT_LENGTH];
+  unsigned int context_len[2];
+
 
   /* Methods */
 
@@ -206,6 +215,8 @@ struct hb_buffer_t {
   HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
 
   HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
+
+  inline void clear_context (unsigned int side) { context_len[side] = 0; }
 };
 
 
index 6da196f..2f8f511 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 1998-2004  David Turner and Werner Lemberg
  * Copyright © 2004,2007,2009,2010  Red Hat, Inc.
- * Copyright © 2011  Google, Inc.
+ * Copyright © 2011,2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *
@@ -158,6 +158,9 @@ hb_buffer_t::reset (void)
   serial = 0;
   memset (allocated_var_bytes, 0, sizeof allocated_var_bytes);
   memset (allocated_var_owner, 0, sizeof allocated_var_owner);
+
+  memset (context, 0, sizeof context);
+  memset (context_len, 0, sizeof context_len);
 }
 
 void
@@ -570,6 +573,8 @@ hb_buffer_get_empty (void)
     true, /* in_error */
     true, /* have_output */
     true  /* have_positions */
+
+    /* Zero is good enough for everything else. */
   };
 
   return const_cast<hb_buffer_t *> (&_hb_buffer_nil);
@@ -723,6 +728,7 @@ hb_buffer_add (hb_buffer_t    *buffer,
               unsigned int    cluster)
 {
   buffer->add (codepoint, mask, cluster);
+  buffer->clear_context (1);
 }
 
 hb_bool_t
@@ -743,6 +749,11 @@ hb_buffer_set_length (hb_buffer_t  *buffer,
   }
 
   buffer->len = length;
+
+  if (!length)
+    buffer->clear_context (0);
+  buffer->clear_context (1);
+
   return true;
 }
 
@@ -817,13 +828,38 @@ hb_buffer_add_utf (hb_buffer_t  *buffer,
 
   buffer->ensure (buffer->len + item_length * sizeof (T) / 4);
 
-  const T *next = (const T *) text + item_offset;
+  if (!buffer->len)
+  {
+    /* Add pre-context */
+    buffer->clear_context (0);
+    const T *prev = text + item_offset;
+    const T *start = text;
+    while (start < prev && buffer->context_len[0] < buffer->CONTEXT_LENGTH)
+    {
+      hb_codepoint_t u;
+      prev = hb_utf_prev (prev, start, &u);
+      buffer->context[0][buffer->context_len[0]++] = u;
+    }
+  }
+
+  const T *next = text + item_offset;
   const T *end = next + item_length;
-  while (next < end) {
+  while (next < end)
+  {
     hb_codepoint_t u;
     const T *old_next = next;
     next = hb_utf_next (next, end, &u);
-    hb_buffer_add (buffer, u, 1,  old_next - (const T *) text);
+    buffer->add (u, 1,  old_next - (const T *) text);
+  }
+
+  /* Add post-context */
+  buffer->clear_context (1);
+  end = text + text_length;
+  while (next < end && buffer->context_len[1] < buffer->CONTEXT_LENGTH)
+  {
+    hb_codepoint_t u;
+    next = hb_utf_next (next, end, &u);
+    buffer->context[1][buffer->context_len[1]++] = u;
   }
 
   buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
index d89dce3..dc63d1b 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright © 1998-2004  David Turner and Werner Lemberg
  * Copyright © 2004,2007,2009  Red Hat, Inc.
- * Copyright © 2011  Google, Inc.
+ * Copyright © 2011,2012  Google, Inc.
  *
  *  This is part of HarfBuzz, a text shaping library.
  *