Add buffer flags

New API:

	hb_buffer_flags_t

	HB_BUFFER_FLAGS_DEFAULT
	HB_BUFFER_FLAG_BOT
	HB_BUFFER_FLAG_EOT
	HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES

	hb_buffer_set_flags()
	hb_buffer_get_flags()

We use the BOT flag to decide whether to insert dottedcircle if the
first char in the buffer is a combining mark.

The PRESERVE_DEFAULT_IGNORABLES flag prevents removal of characters like
ZWNJ/ZWJ/...
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 4e92fb5..6cfb115 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -89,6 +89,7 @@
 
   hb_unicode_funcs_t *unicode; /* Unicode functions */
   hb_segment_properties_t props; /* Script, language, direction */
+  hb_buffer_flags_t flags; /* BOT / EOT / etc. */
 
   /* Buffer contents */
 
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 6aff7b9..b770144 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -153,6 +153,7 @@
 
   hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
   props = default_props;
+  flags = HB_BUFFER_FLAGS_DEFAULT;
 
   content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
   in_error = false;
@@ -590,6 +591,7 @@
 
     const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
     _HB_BUFFER_PROPS_DEFAULT,
+    HB_BUFFER_FLAGS_DEFAULT,
 
     HB_BUFFER_CONTENT_TYPE_INVALID,
     true, /* in_error */
@@ -724,6 +726,22 @@
   return buffer->props.language;
 }
 
+void
+hb_buffer_set_flags (hb_buffer_t       *buffer,
+		     hb_buffer_flags_t  flags)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->flags = flags;
+}
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer)
+{
+  return buffer->flags;
+}
+
 
 void
 hb_buffer_reset (hb_buffer_t *buffer)
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index fbd809c..533bac8 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -68,6 +68,12 @@
   HB_BUFFER_CONTENT_TYPE_GLYPHS
 } hb_buffer_content_type_t;
 
+typedef enum {
+  HB_BUFFER_FLAGS_DEFAULT			= 0x00000000,
+  HB_BUFFER_FLAG_BOT				= 0x00000001, /* Beginning-of-text */
+  HB_BUFFER_FLAG_EOT				= 0x00000002, /* End-of-text */
+  HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES	= 0x00000004
+} hb_buffer_flags_t;
 
 hb_buffer_t *
 hb_buffer_create (void);
@@ -129,6 +135,13 @@
 hb_language_t
 hb_buffer_get_language (hb_buffer_t *buffer);
 
+void
+hb_buffer_set_flags (hb_buffer_t       *buffer,
+		     hb_buffer_flags_t  flags);
+
+hb_buffer_flags_t
+hb_buffer_get_flags (hb_buffer_t *buffer);
+
 
 /* Resets the buffer.  Afterwards it's as if it was just created,
  * except that it has a larger buffer allocated perhaps... */
diff --git a/src/hb-ot-shape-complex-arabic.cc b/src/hb-ot-shape-complex-arabic.cc
index cba7933..59c9716 100644
--- a/src/hb-ot-shape-complex-arabic.cc
+++ b/src/hb-ot-shape-complex-arabic.cc
@@ -250,17 +250,18 @@
   HB_BUFFER_ALLOCATE_VAR (buffer, arabic_shaping_action);
 
   /* Check pre-context */
-  for (unsigned int i = 0; i < buffer->context_len[0]; i++)
-  {
-    unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
+  if (!(buffer->flags & HB_BUFFER_FLAG_BOT))
+    for (unsigned int i = 0; i < buffer->context_len[0]; i++)
+    {
+      unsigned int this_type = get_joining_type (buffer->context[0][i], buffer->unicode->general_category (buffer->context[0][i]));
 
-    if (unlikely (this_type == JOINING_TYPE_T))
-      continue;
+      if (unlikely (this_type == JOINING_TYPE_T))
+	continue;
 
-    const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
-    state = entry->next_state;
-    break;
-  }
+      const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+      state = entry->next_state;
+      break;
+    }
 
   for (unsigned int i = 0; i < count; i++)
   {
@@ -282,18 +283,19 @@
     state = entry->next_state;
   }
 
-  for (unsigned int i = 0; i < buffer->context_len[1]; i++)
-  {
-    unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[0][i]));
+  if (!(buffer->flags & HB_BUFFER_FLAG_EOT))
+    for (unsigned int i = 0; i < buffer->context_len[1]; i++)
+    {
+      unsigned int this_type = get_joining_type (buffer->context[1][i], buffer->unicode->general_category (buffer->context[0][i]));
 
-    if (unlikely (this_type == JOINING_TYPE_T))
-      continue;
+      if (unlikely (this_type == JOINING_TYPE_T))
+	continue;
 
-    const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
-    if (entry->prev_action != NONE && prev != (unsigned int) -1)
-      buffer->info[prev].arabic_shaping_action() = entry->prev_action;
-    break;
-  }
+      const arabic_state_table_entry *entry = &arabic_state_table[state][this_type];
+      if (entry->prev_action != NONE && prev != (unsigned int) -1)
+	buffer->info[prev].arabic_shaping_action() = entry->prev_action;
+      break;
+    }
 
 
   HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 26ec4db..634fe6f 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -237,7 +237,7 @@
 static void
 hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
 {
-  if (buffer->context_len[0] ||
+  if (!(buffer->flags & HB_BUFFER_FLAG_BOT) ||
       _hb_glyph_info_get_general_category (&buffer->info[0]) !=
       HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)
     return;
@@ -509,8 +509,11 @@
 /* Post-process */
 
 static void
-hb_ot_hide_zerowidth (hb_ot_shape_context_t *c)
+hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
 {
+  if (c->buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES)
+    return;
+
   hb_codepoint_t space = 0;
 
   unsigned int count = c->buffer->len;
@@ -554,7 +557,7 @@
   hb_ot_substitute (c);
   hb_ot_position (c);
 
-  hb_ot_hide_zerowidth (c);
+  hb_ot_hide_default_ignorables (c);
 
   HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props1);
   HB_BUFFER_DEALLOCATE_VAR (c->buffer, unicode_props0);