Add hb_buffer_[sg]et_content_type

And hb_buffer_content_type_t and enum values.
diff --git a/TODO b/TODO
index be3c7c6..d94d875 100644
--- a/TODO
+++ b/TODO
@@ -91,3 +91,4 @@
 - hb_cache_t and relatives
 
 - hb_feature_to/from_string
+- hb_buffer_[sg]et_contents
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 456e1b8..f5d64f3 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -92,6 +92,8 @@
 
   /* Buffer contents */
 
+  hb_buffer_content_type_t content_type;
+
   bool in_error; /* Allocation failed */
   bool have_output; /* Whether we have an output buffer going on */
   bool have_positions; /* Whether we have positions */
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index f25a8bc..fec9225 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -147,6 +147,7 @@
   hb_segment_properties_t default_props = _HB_BUFFER_PROPS_DEFAULT;
   props = default_props;
 
+  content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
   in_error = false;
   have_output = false;
   have_positions = false;
@@ -446,6 +447,9 @@
 void
 hb_buffer_t::guess_properties (void)
 {
+  if (unlikely (!len)) return;
+  assert (content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
   /* If script is set to INVALID, guess from buffer contents */
   if (props.script == HB_SCRIPT_INVALID) {
     for (unsigned int i = 0; i < len; i++) {
@@ -564,6 +568,7 @@
     const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil),
     _HB_BUFFER_PROPS_DEFAULT,
 
+    HB_BUFFER_CONTENT_TYPE_INVALID,
     true, /* in_error */
     true, /* have_output */
     true  /* have_positions */
@@ -610,6 +615,20 @@
 
 
 void
+hb_buffer_set_content_type (hb_buffer_t              *buffer,
+			    hb_buffer_content_type_t  content_type)
+{
+  buffer->content_type = content_type;
+}
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer)
+{
+  return buffer->content_type;
+}
+
+
+void
 hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
 			     hb_unicode_funcs_t *unicode)
 {
@@ -849,6 +868,11 @@
 		    unsigned int  item_offset,
 		    int           item_length)
 {
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
 #define UTF_NEXT(S, E, U)	hb_utf8_next (S, E, &(U))
   ADD_UTF (uint8_t);
 #undef UTF_NEXT
@@ -883,6 +907,11 @@
 		     unsigned int    item_offset,
 		     int            item_length)
 {
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
 #define UTF_NEXT(S, E, U)	hb_utf16_next (S, E, &(U))
   ADD_UTF (uint16_t);
 #undef UTF_NEXT
@@ -895,6 +924,11 @@
 		     unsigned int    item_offset,
 		     int             item_length)
 {
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE ||
+	  (!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID));
+  if (unlikely (hb_object_is_inert (buffer)))
+    return;
+  buffer->content_type = HB_BUFFER_CONTENT_TYPE_UNICODE;
 #define UTF_NEXT(S, E, U)	((U) = *(S), (S)+1)
   ADD_UTF (uint32_t);
 #undef UTF_NEXT
diff --git a/src/hb-buffer.h b/src/hb-buffer.h
index aebf482..d89dce3 100644
--- a/src/hb-buffer.h
+++ b/src/hb-buffer.h
@@ -62,6 +62,12 @@
   hb_var_int_t   var;
 } hb_glyph_position_t;
 
+typedef enum {
+  HB_BUFFER_CONTENT_TYPE_INVALID = 0,
+  HB_BUFFER_CONTENT_TYPE_UNICODE,
+  HB_BUFFER_CONTENT_TYPE_GLYPHS
+} hb_buffer_content_type_t;
+
 
 hb_buffer_t *
 hb_buffer_create (void);
@@ -88,6 +94,14 @@
 
 
 void
+hb_buffer_set_content_type (hb_buffer_t              *buffer,
+			    hb_buffer_content_type_t  content_type);
+
+hb_buffer_content_type_t
+hb_buffer_get_content_type (hb_buffer_t *buffer);
+
+
+void
 hb_buffer_set_unicode_funcs (hb_buffer_t        *buffer,
 			     hb_unicode_funcs_t *unicode_funcs);
 
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 6619c19..4d64823 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -253,11 +253,16 @@
   if (unlikely (!buffer->len))
     return true;
 
+  assert (buffer->content_type == HB_BUFFER_CONTENT_TYPE_UNICODE);
+
   buffer->guess_properties ();
 
   hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
   hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
   hb_shape_plan_destroy (shape_plan);
+
+  if (res)
+    buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
   return res;
 }