Add API for setting invisible-codepoint

Fixes https://github.com/harfbuzz/harfbuzz/issues/1216

New API:
hb_buffer_set_invisible_codepoint()
hb_buffer_get_invisible_codepoint()

hb-shape / hb-view --invisible-codepoint
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index b93b243..0b8593f 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -219,6 +219,7 @@
   unicode = hb_unicode_funcs_reference (hb_unicode_funcs_get_default ());
   flags = HB_BUFFER_FLAG_DEFAULT;
   replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
+  invisible = 0;
 
   clear ();
 }
@@ -665,6 +666,7 @@
   HB_BUFFER_FLAG_DEFAULT,
   HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
   HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
+  0, /* invisible */
   HB_BUFFER_SCRATCH_FLAG_DEFAULT,
   HB_BUFFER_MAX_LEN_DEFAULT,
   HB_BUFFER_MAX_OPS_DEFAULT,
@@ -1167,6 +1169,46 @@
 
 
 /**
+ * hb_buffer_set_invisible_codepoint:
+ * @buffer: an #hb_buffer_t.
+ * @invisible: the invisible #hb_codepoint_t
+ *
+ * Sets the #hb_codepoint_t that replaces invisible characters in
+ * the shaping result.  If set to zero (default), the glyph for the
+ * U+0020 SPACE character is used.  Otherwise, this value is used
+ * verbatim.
+ *
+ * Since: REPLACEME
+ **/
+void
+hb_buffer_set_invisible_codepoint (hb_buffer_t    *buffer,
+				   hb_codepoint_t  invisible)
+{
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+
+  buffer->invisible = invisible;
+}
+
+/**
+ * hb_buffer_get_invisible_codepoint:
+ * @buffer: an #hb_buffer_t.
+ *
+ * See hb_buffer_set_invisible_codepoint().
+ *
+ * Return value: 
+ * The @buffer invisible #hb_codepoint_t.
+ *
+ * Since: REPLACEME
+ **/
+hb_codepoint_t
+hb_buffer_get_invisible_codepoint (hb_buffer_t    *buffer)
+{
+  return buffer->invisible;
+}
+
+
+/**
  * hb_buffer_reset:
  * @buffer: an #hb_buffer_t.
  *
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index 4c746f4..d99ae7d 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -341,6 +341,13 @@
 HB_EXTERN hb_codepoint_t
 hb_buffer_get_replacement_codepoint (hb_buffer_t    *buffer);
 
+HB_EXTERN void
+hb_buffer_set_invisible_codepoint (hb_buffer_t    *buffer,
+				   hb_codepoint_t  invisible);
+
+HB_EXTERN hb_codepoint_t
+hb_buffer_get_invisible_codepoint (hb_buffer_t    *buffer);
+
 
 HB_EXTERN void
 hb_buffer_reset (hb_buffer_t *buffer);
diff --git a/src/hb-buffer.hh b/src/hb-buffer.hh
index 33ddcbc..9126822 100644
--- a/src/hb-buffer.hh
+++ b/src/hb-buffer.hh
@@ -93,6 +93,7 @@
   hb_buffer_flags_t flags; /* BOT / EOT / etc. */
   hb_buffer_cluster_level_t cluster_level;
   hb_codepoint_t replacement; /* U+FFFD or something else. */
+  hb_codepoint_t invisible; /* 0 or something else. */
   hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
   unsigned int max_len; /* Maximum allowed len. */
   int max_ops; /* Maximum allowed operations. */
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 453d995..3b79ef4 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -548,15 +548,15 @@
   if (i == count)
     return;
 
-  hb_codepoint_t space;
+  hb_codepoint_t invisible = c->buffer->invisible;
   if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
-      c->font->get_nominal_glyph (' ', &space))
+      (invisible || c->font->get_nominal_glyph (' ', &invisible)))
   {
-    /* Replace default-ignorables with a zero-advance space glyph. */
+    /* Replace default-ignorables with a zero-advance invisible glyph. */
     for (/*continue*/; i < count; i++)
     {
       if (_hb_glyph_info_is_default_ignorable (&info[i]))
-	info[i].codepoint = space;
+	info[i].codepoint = invisible;
     }
   }
   else