[subset] convert subset input flags into bit flags.

Store the flags in a bit set. Updates the public api to work with the bit set directly.
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index 47f1f6a..e1d3bcf 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -54,16 +54,8 @@
   input->layout_features = hb_set_create ();
   input->drop_tables = hb_set_create ();
   input->no_subset_tables = hb_set_create ();
-  input->drop_hints = false;
-  input->desubroutinize = false;
-  input->retain_gids = false;
-  input->name_legacy = false;
-  input->overlaps_flag = false;
-  input->notdef_outline = false;
-  input->glyph_names = false;
-  input->no_prune_unicode_ranges = false;
-  input->retain_all_layout_features = false;
-  input->passthrough_unrecognized = false;
+
+  input->flags = HB_SUBSET_FLAGS_NONE;
 
   hb_tag_t default_drop_tables[] = {
     // Layout disabled by default
@@ -362,98 +354,39 @@
 
 
 /**
- * hb_subset_input_get_flag:
+ * hb_subset_input_get_flags:
  * @input: a #hb_subset_input_t object.
- * @flag: which flag to check.
  *
- * Get the value of the specified flag.
- *
- * Return value: value of the specified flag.
+ * Return value: the subsetting flags bit array.
  *
  * Since: REPLACE
  **/
-HB_EXTERN hb_bool_t
-hb_subset_input_get_flag (hb_subset_input_t *input,
-			  hb_subset_flag_t flag)
+HB_EXTERN hb_subset_flags_t
+hb_subset_input_get_flags (hb_subset_input_t *input)
 {
-  switch (flag)
-  {
-    case HB_SUBSET_FLAG_HINTING:
-      return !input->drop_hints;
-    case HB_SUBSET_FLAG_RETAIN_GIDS:
-      return input->retain_gids;
-    case HB_SUBSET_FLAG_DESUBROUTINIZE:
-      return input->desubroutinize;
-    case HB_SUBSET_FLAG_NAME_LEGACY:
-      return input->name_legacy;
-    case HB_SUBSET_FLAG_SET_OVERLAPS_FLAG:
-      return input->overlaps_flag;
-    case HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED:
-      return input->passthrough_unrecognized;
-    case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
-      return input->notdef_outline;
-    case HB_SUBSET_FLAG_GLYPH_NAMES:
-      return input->glyph_names;
-    case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
-      return input->no_prune_unicode_ranges;
-    case HB_SUBSET_FLAG_RETAIN_ALL_FEATURES:
-      return input->retain_all_layout_features;
-    default:
-      return false;
-  }
+  return input->flags;
 }
 
 /**
- * hb_subset_input_set_flag:
+ * hb_subset_input_set_flags:
  * @input: a #hb_subset_input_t object.
  * @flag: which flag to set.
- * @value: new value for the flag.
+ * @mask: bit mask which specifies which flags to change.
+ * @value: bit set of new values for those flags.
  *
- * Set the specified flag to @value.
+ * Updates the flags specified by the mask to the values in value.
  *
  * Since: REPLACE
  **/
 HB_EXTERN void
-hb_subset_input_set_flag (hb_subset_input_t *input,
-			  hb_subset_flag_t flag,
-			  hb_bool_t value)
+hb_subset_input_set_flags (hb_subset_input_t *input,
+			   hb_subset_flags_t mask,
+			   hb_subset_flags_t value)
 {
-  switch (flag)
-  {
-    case HB_SUBSET_FLAG_HINTING:
-      input->drop_hints = !value;
-      break;
-    case HB_SUBSET_FLAG_RETAIN_GIDS:
-      input->retain_gids = value;
-      break;
-    case HB_SUBSET_FLAG_DESUBROUTINIZE:
-      input->desubroutinize = value;
-      break;
-    case HB_SUBSET_FLAG_NAME_LEGACY:
-      input->name_legacy = value;
-      break;
-    case HB_SUBSET_FLAG_SET_OVERLAPS_FLAG:
-      input->overlaps_flag = value;
-      break;
-    case HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED:
-      input->passthrough_unrecognized = value;
-      break;
-    case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
-      input->notdef_outline = value;
-      break;
-    case HB_SUBSET_FLAG_GLYPH_NAMES:
-      input->glyph_names = value;
-      break;
-    case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
-      input->no_prune_unicode_ranges = value;
-      break;
-    case HB_SUBSET_FLAG_RETAIN_ALL_FEATURES:
-      input->retain_all_layout_features = value;
-      break;
-    default:
-      // Do nothing.
-      break;
-  }
+  // Set desired flags.
+  input->flags = (hb_subset_flags_t) (input->flags | (mask & value));
+  // Clear desired flags.
+  input->flags = (hb_subset_flags_t) (input->flags & ~(mask & ~value));
 }
 
 /**
diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh
index ddbd4fb..89da38f 100644
--- a/src/hb-subset-input.hh
+++ b/src/hb-subset-input.hh
@@ -46,17 +46,7 @@
   hb_set_t *drop_tables;
   hb_set_t *layout_features;
 
-  //use hb_bool_t to be consistent with G option parser
-  hb_bool_t drop_hints;
-  hb_bool_t desubroutinize;
-  hb_bool_t retain_gids;
-  hb_bool_t name_legacy;
-  hb_bool_t overlaps_flag;
-  hb_bool_t notdef_outline;
-  hb_bool_t glyph_names;
-  hb_bool_t no_prune_unicode_ranges;
-  hb_bool_t retain_all_layout_features;
-  hb_bool_t passthrough_unrecognized;
+  hb_subset_flags_t flags;
 
   /* TODO
    *
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 76b73fe..5a34044 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -423,16 +423,16 @@
     return const_cast<hb_subset_plan_t *> (&Null (hb_subset_plan_t));
 
   plan->successful = true;
-  plan->drop_hints = input->drop_hints;
-  plan->desubroutinize = input->desubroutinize;
-  plan->retain_gids = input->retain_gids;
-  plan->name_legacy = input->name_legacy;
-  plan->overlaps_flag = input->overlaps_flag;
-  plan->notdef_outline = input->notdef_outline;
-  plan->glyph_names = input->glyph_names;
-  plan->prune_unicode_ranges = !input->no_prune_unicode_ranges;
-  plan->retain_all_layout_features = input->retain_all_layout_features;
-  plan->passthrough_unrecognized = input->passthrough_unrecognized;
+  plan->drop_hints = input->flags & HB_SUBSET_FLAGS_NO_HINTING;
+  plan->desubroutinize = input->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE;
+  plan->retain_gids = input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
+  plan->name_legacy = input->flags & HB_SUBSET_FLAGS_NAME_LEGACY;
+  plan->overlaps_flag = input->flags & HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG;
+  plan->notdef_outline = input->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE;
+  plan->glyph_names = input->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
+  plan->prune_unicode_ranges = !(input->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES);
+  plan->retain_all_layout_features = input->flags & HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES;
+  plan->passthrough_unrecognized = input->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED;
   plan->unicodes = hb_set_create ();
   plan->name_ids = hb_set_copy (input->name_ids);
   _nameid_closure (face, plan->name_ids);
@@ -478,7 +478,7 @@
 			    !input->drop_tables->has (HB_OT_TAG_GDEF));
 
   _create_old_gid_to_new_gid_map (face,
-				  input->retain_gids,
+                                  input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
 				  plan->_glyphset,
 				  plan->glyph_map,
 				  plan->reverse_glyph_map,
diff --git a/src/hb-subset.h b/src/hb-subset.h
index cf08a50..45d7708 100644
--- a/src/hb-subset.h
+++ b/src/hb-subset.h
@@ -40,33 +40,36 @@
 typedef struct hb_subset_input_t hb_subset_input_t;
 
 /**
- * hb_subset_flag_t:
- * @HB_SUBSET_FLAG_HINTING: If set hinting instructions will be retained in
- * the produced subset. Otherwise hinting instructions will be dropped.
+ * TODO(garretrieger): update to match added values, and no hinting change.
+ * hb_subset_flags_t:
+ * @HB_SUBSET_FLAGS_NONE: bit set with no flags set.
+ * @HB_SUBSET_FLAGS_NO_HINTING: If set hinting instructions will be dropped in
+ * the produced subset. Otherwise hinting instructions will be retained.
  * Defaults to true.
- * @HB_SUBSET_FLAG_RETAIN_GIDS: If set glyph indices will not be modified in
+ * @HB_SUBSET_FLAGS_RETAIN_GIDS: If set glyph indices will not be modified in
  * the produced subset. If glyphs are dropped their indices will be retained
  * as an empty glyph. Defaults to false.
- * @HB_SUBSET_FLAG_DESUBROUTINIZE: If set and subsetting a CFF font the
+ * @HB_SUBSET_FLAGS_DESUBROUTINIZE: If set and subsetting a CFF font the
  * subsetter will attempt to remove subroutines from the CFF glyphs.
  * Defaults to false.
- * @HB_SUBSET_FLAG_NAME_LEGACY: If set non-unicode name records will be
+ * @HB_SUBSET_FLAGS_NAME_LEGACY: If set non-unicode name records will be
  * retained in the subset. Defaults to false.
- * @HB_SUBSET_FLAG_SET_OVERLAPS_FLAG:  If set the subsetter will set the
+ * @HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG:  If set the subsetter will set the
  * OVERLAP_SIMPLE flag on each simple glyph. Defaults to false.
- * @HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED: If set the subsetter will not
+ * @HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED: If set the subsetter will not
  * drop unrecognized tables and instead pass them through untouched.
  * Defaults to false.
- * @HB_SUBSET_FLAG_NOTDEF_OUTLINE: If set the notdef glyph outline will be
+ * @HB_SUBSET_FLAGS_NOTDEF_OUTLINE: If set the notdef glyph outline will be
  * retained in the final subset. Defaults to false.
- * @HB_SUBSET_FLAG_GLYPH_NAMES: If set the PS glyph names will be retained
+ * @HB_SUBSET_FLAGS_GLYPH_NAMES: If set the PS glyph names will be retained
  * in the final subset. Defaults to false.
- * @HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
+ * @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
  * OS/2 will not be recalculated.
- * @HB_SUBSET_FLAG_RETAIN_ALL_FEATURES: If set all layout features will be
+ * @HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES: If set all layout features will be
  * retained. If unset then the set accessed by
  * hb_subset_input_layout_features_set() will be used to determine the features
  * to be retained.
+ * HB_SUBSET_FLAGS_ALL: bit set with all flags set.
  *
  * List of boolean properties that can be configured on the subset input.
  *
@@ -74,17 +77,19 @@
  **/
 typedef enum
 {
-  HB_SUBSET_FLAG_HINTING = 0,
-  HB_SUBSET_FLAG_RETAIN_GIDS,
-  HB_SUBSET_FLAG_DESUBROUTINIZE,
-  HB_SUBSET_FLAG_NAME_LEGACY,
-  HB_SUBSET_FLAG_SET_OVERLAPS_FLAG,
-  HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED,
-  HB_SUBSET_FLAG_NOTDEF_OUTLINE,
-  HB_SUBSET_FLAG_GLYPH_NAMES,
-  HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES,
-  HB_SUBSET_FLAG_RETAIN_ALL_FEATURES,
-} hb_subset_flag_t;
+  HB_SUBSET_FLAGS_NONE = 0,
+  HB_SUBSET_FLAGS_NO_HINTING = 1,
+  HB_SUBSET_FLAGS_RETAIN_GIDS = 1 << 1,
+  HB_SUBSET_FLAGS_DESUBROUTINIZE = 1 << 2,
+  HB_SUBSET_FLAGS_NAME_LEGACY = 1 << 3,
+  HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG = 1 << 4,
+  HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED = 1 << 5,
+  HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 1 << 6,
+  HB_SUBSET_FLAGS_GLYPH_NAMES = 1 << 7,
+  HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 1 << 8,
+  HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES = 1 << 9,
+  HB_SUBSET_FLAGS_ALL = -1,
+} hb_subset_flags_t;
 
 HB_EXTERN hb_subset_input_t *
 hb_subset_input_create_or_fail (void);
@@ -127,14 +132,13 @@
 HB_EXTERN hb_set_t *
 hb_subset_input_drop_tables_set (hb_subset_input_t *input);
 
-HB_EXTERN hb_bool_t
-hb_subset_input_get_flag (hb_subset_input_t *input,
-			  hb_subset_flag_t flag);
+HB_EXTERN hb_subset_flags_t
+hb_subset_input_get_flags (hb_subset_input_t *input);
 
 HB_EXTERN void
-hb_subset_input_set_flag (hb_subset_input_t *input,
-			  hb_subset_flag_t flag,
-			  hb_bool_t value);
+hb_subset_input_set_flags (hb_subset_input_t *input,
+                           hb_subset_flags_t mask,
+                           hb_subset_flags_t value);
 
 HB_EXTERN hb_face_t *
 hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h
index 1fc5a48..261a687 100644
--- a/test/api/hb-subset-test.h
+++ b/test/api/hb-subset-test.h
@@ -75,7 +75,9 @@
   hb_set_t *name_langids = hb_subset_input_namelangid_set (input);
   hb_set_add_range (name_langids, 0, 0x5FFF);
 
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_NAME_LEGACY, true);
+  hb_subset_input_set_flags (input,
+                             HB_SUBSET_FLAGS_NAME_LEGACY,
+                             HB_SUBSET_FLAGS_ALL);
   return input;
 }
 
diff --git a/test/api/test-subset-cff1.c b/test/api/test-subset-cff1.c
index 4f70f2d..16b076c 100644
--- a/test/api/test-subset-cff1.c
+++ b/test/api/test-subset-cff1.c
@@ -80,7 +80,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -103,7 +103,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_DESUBROUTINIZE, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -126,8 +126,9 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
+  hb_subset_input_set_flags (input,
+                             HB_SUBSET_FLAGS_NO_HINTING | HB_SUBSET_FLAGS_DESUBROUTINIZE,
+                             HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -170,7 +171,7 @@
   hb_set_add (codepoints, 0x41);
   hb_set_add (codepoints, 0x4C2E);
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input);
   hb_set_destroy (codepoints);
 
@@ -193,7 +194,7 @@
   hb_set_add (codepoints, 0x41);
   hb_set_add (codepoints, 0x4C2E);
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_DESUBROUTINIZE, HB_SUBSET_FLAGS_ALL);
   face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input);
   hb_set_destroy (codepoints);
 
@@ -216,8 +217,9 @@
   hb_set_add (codepoints, 0x41);
   hb_set_add (codepoints, 0x4C2E);
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
+  hb_subset_input_set_flags (input,
+                             HB_SUBSET_FLAGS_NO_HINTING | HB_SUBSET_FLAGS_DESUBROUTINIZE,
+                             HB_SUBSET_FLAGS_ALL);
   face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input);
   hb_set_destroy (codepoints);
 
@@ -279,7 +281,7 @@
   hb_face_t *face_test;
   hb_set_add (codepoints, 0x69);  /* i */
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   face_test = hb_subset_test_create_subset (face, input);
   hb_set_destroy (codepoints);
 
@@ -302,7 +304,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -325,7 +327,7 @@
   hb_set_add (codepoints, 0x41);
   hb_set_add (codepoints, 0x4C2E);
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_41_3041_4c2e_subset = hb_subset_test_create_subset (face_41_3041_4c2e, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset-cff2.c b/test/api/test-subset-cff2.c
index 835bdf3..81ec3e8 100644
--- a/test/api/test-subset-cff2.c
+++ b/test/api/test-subset-cff2.c
@@ -80,7 +80,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -103,7 +103,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_DESUBROUTINIZE, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -126,8 +126,9 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_DESUBROUTINIZE, true);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input,
+                             HB_SUBSET_FLAGS_DESUBROUTINIZE | HB_SUBSET_FLAGS_NO_HINTING,
+                             HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -150,7 +151,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index a6a6bbf..9b618e8 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -92,7 +92,7 @@
   hb_set_add (codepoints, 508);
 
   hb_subset_input_t* input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_SET_OVERLAPS_FLAG, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG, HB_SUBSET_FLAGS_ALL);
   face_abcAE_subset = hb_subset_test_create_subset (face_abcAE, input);
   hb_set_destroy (codepoints);
 
@@ -239,7 +239,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -263,7 +263,7 @@
   hb_face_t *face_generated_subset;
   hb_set_add (codepoints, 0x1fc);
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
 
   face_generated_subset = hb_subset_test_create_subset (face_components, input);
   hb_set_destroy (codepoints);
@@ -298,7 +298,7 @@
   }
 
   input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, false);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING, HB_SUBSET_FLAGS_ALL);
   hb_set_destroy (codepoints);
 
   face_subset = hb_subset_or_fail (face, input);
@@ -320,7 +320,7 @@
   hb_set_add (codepoints, 99);
 
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -344,7 +344,7 @@
   hb_set_add (codepoints, 97);
 
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset-gvar.c b/test/api/test-subset-gvar.c
index fc5f706..56f0558 100644
--- a/test/api/test-subset-gvar.c
+++ b/test/api/test-subset-gvar.c
@@ -79,7 +79,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset-hvar.c b/test/api/test-subset-hvar.c
index 847e61a..6375af6 100644
--- a/test/api/test-subset-hvar.c
+++ b/test/api/test-subset-hvar.c
@@ -79,7 +79,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
@@ -160,7 +160,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset-vvar.c b/test/api/test-subset-vvar.c
index 6f4c9ad..e28cac1 100644
--- a/test/api/test-subset-vvar.c
+++ b/test/api/test-subset-vvar.c
@@ -79,7 +79,7 @@
   hb_set_add (codepoints, 'a');
   hb_set_add (codepoints, 'c');
   hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, true);
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS, HB_SUBSET_FLAGS_ALL);
   face_abc_subset = hb_subset_test_create_subset (face_abc, input);
   hb_set_destroy (codepoints);
 
diff --git a/test/api/test-subset.c b/test/api/test-subset.c
index 2c35604..9ef3946 100644
--- a/test/api/test-subset.c
+++ b/test/api/test-subset.c
@@ -93,6 +93,46 @@
   hb_face_destroy (face);
 }
 
+static void
+test_subset_set_flags (void)
+{
+  hb_subset_input_t *input = hb_subset_input_create_or_fail ();
+
+  g_assert (hb_subset_input_get_flags (input) == HB_SUBSET_FLAGS_NONE);
+
+  hb_subset_input_set_flags (input,
+                             HB_SUBSET_FLAGS_NAME_LEGACY |
+                             HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+                             HB_SUBSET_FLAGS_GLYPH_NAMES,
+                             HB_SUBSET_FLAGS_ALL);
+
+  g_assert (hb_subset_input_get_flags (input) ==
+            (hb_subset_flags_t) (
+            HB_SUBSET_FLAGS_NAME_LEGACY |
+            HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+            HB_SUBSET_FLAGS_GLYPH_NAMES));
+
+  hb_subset_input_set_flags (input,
+
+                             HB_SUBSET_FLAGS_NAME_LEGACY |
+                             HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+                             HB_SUBSET_FLAGS_GLYPH_NAMES |
+                             HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES,
+
+                             HB_SUBSET_FLAGS_NAME_LEGACY |
+                             HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+                             HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES);
+
+  g_assert (hb_subset_input_get_flags (input) ==
+            (hb_subset_flags_t) (
+            HB_SUBSET_FLAGS_NAME_LEGACY |
+            HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
+            HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES));
+
+
+  hb_subset_input_destroy (input);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -101,6 +141,7 @@
   hb_test_add (test_subset_32_tables);
   hb_test_add (test_subset_no_inf_loop);
   hb_test_add (test_subset_crash);
+  hb_test_add (test_subset_set_flags);
 
   return hb_test_run();
 }
diff --git a/test/fuzzing/hb-subset-fuzzer.cc b/test/fuzzing/hb-subset-fuzzer.cc
index c121301..041c886 100644
--- a/test/fuzzing/hb-subset-fuzzer.cc
+++ b/test/fuzzing/hb-subset-fuzzer.cc
@@ -11,22 +11,14 @@
 trySubset (hb_face_t *face,
 	   const hb_codepoint_t text[],
 	   int text_length,
-	   bool drop_hints,
-	   bool drop_layout,
-	   bool retain_gids)
+           hb_subset_flags_t flag_bits)
 {
   hb_subset_input_t *input = hb_subset_input_create_or_fail ();
   if (!input) return;
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_HINTING, !drop_hints);
-  hb_subset_input_set_flag (input, HB_SUBSET_FLAG_RETAIN_GIDS, retain_gids);
-  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
 
-  if (!drop_layout)
-  {
-    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'S', 'U', 'B'));
-    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'P', 'O', 'S'));
-    hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'D', 'E', 'F'));
-  }
+  hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_ALL, flag_bits);
+
+  hb_set_t *codepoints = hb_subset_input_unicode_set (input);
 
   for (int i = 0; i < text_length; i++)
     hb_set_add (codepoints, text[i]);
@@ -51,19 +43,6 @@
   hb_subset_input_destroy (input);
 }
 
-static void
-trySubset (hb_face_t *face,
-	   const hb_codepoint_t text[],
-	   int text_length,
-	   const uint8_t flags[1])
-{
-  bool drop_hints =  flags[0] & (1 << 0);
-  bool drop_layout = flags[0] & (1 << 1);
-  bool retain_gids = flags[0] & (1 << 2);
-  trySubset (face, text, text_length,
-	     drop_hints, drop_layout, retain_gids);
-}
-
 extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
 {
   alloc_state = size; /* see src/failing-alloc.c */
@@ -77,7 +56,7 @@
   hb_face_collect_unicodes (face, output);
   hb_set_destroy (output);
 
-  uint8_t flags[1] = {0};
+  hb_subset_flags_t flags = HB_SUBSET_FLAGS_NONE;
   const hb_codepoint_t text[] =
       {
 	'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
@@ -92,7 +71,7 @@
 	    data + size - sizeof (text_from_data),
 	    sizeof (text_from_data));
 
-    memcpy (flags,
+    memcpy (&flags,
 	    data + size - sizeof (text_from_data) - sizeof (flags),
 	    sizeof (flags));
     unsigned int text_size = sizeof (text_from_data) / sizeof (hb_codepoint_t);
diff --git a/util/hb-subset.cc b/util/hb-subset.cc
index ad196a9..3a69f66 100644
--- a/util/hb-subset.cc
+++ b/util/hb-subset.cc
@@ -43,7 +43,7 @@
 	     const font_options_t *font_opts)
   {
     font = hb_font_reference (font_opts->get_font ());
-    input = hb_subset_input_reference (subset_options.input);
+    input = hb_subset_input_reference (subset_options.get_input ());
   }
 
   void consume_line (const char   *text,
diff --git a/util/options-subset.cc b/util/options-subset.cc
index ff22880..dbabe36 100644
--- a/util/options-subset.cc
+++ b/util/options-subset.cc
@@ -217,9 +217,12 @@
   if (0 == strcmp (arg, "*"))
   {
     if (last_name_char == '-')
+    {
       hb_set_clear (layout_features);
-    else
-      subset_opts->input->retain_all_layout_features = true;
+      *subset_opts->bool_for (HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES) = false;
+    } else {
+      *subset_opts->bool_for (HB_SUBSET_FLAGS_RETAIN_ALL_FEATURES) = true;
+    }
     return true;
   }
 
@@ -288,14 +291,14 @@
 {
   GOptionEntry entries[] =
   {
-    {"no-hinting", 0, 0, G_OPTION_ARG_NONE,  &this->input->drop_hints,   "Whether to drop hints",   nullptr},
-    {"retain-gids", 0, 0, G_OPTION_ARG_NONE,  &this->input->retain_gids,   "If set don't renumber glyph ids in the subset.",   nullptr},
+    {"no-hinting", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_NO_HINTING),   "Whether to drop hints",   nullptr},
+    {"retain-gids", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_RETAIN_GIDS),   "If set don't renumber glyph ids in the subset.",   nullptr},
     {"gids", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_gids,  "Specify glyph IDs or ranges to include in the subset", "list of comma/whitespace-separated int numbers or ranges"},
-    {"desubroutinize", 0, 0, G_OPTION_ARG_NONE,  &this->input->desubroutinize,   "Remove CFF/CFF2 use of subroutines",   nullptr},
+    {"desubroutinize", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_DESUBROUTINIZE),   "Remove CFF/CFF2 use of subroutines",   nullptr},
     {"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_nameids,  "Subset specified nameids", "list of int numbers"},
     {"name-IDs-", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_nameids,  "Subset specified nameids", "list of int numbers"},
     {"name-IDs+", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_nameids,  "Subset specified nameids", "list of int numbers"},
-    {"name-legacy", 0, 0, G_OPTION_ARG_NONE,  &this->input->name_legacy,   "Keep legacy (non-Unicode) 'name' table entries",   nullptr},
+    {"name-legacy", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_NAME_LEGACY),   "Keep legacy (non-Unicode) 'name' table entries",   nullptr},
     {"name-languages", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_name_languages,  "Subset nameRecords with specified language IDs", "list of int numbers"},
     {"name-languages-", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_name_languages,  "Subset nameRecords with specified language IDs", "list of int numbers"},
     {"name-languages+", 0, 0, G_OPTION_ARG_CALLBACK,  (gpointer) &parse_name_languages,  "Subset nameRecords with specified language IDs", "list of int numbers"},
@@ -308,11 +311,11 @@
     {"num-iterations", 'n', 0, G_OPTION_ARG_INT,
      &this->num_iterations,
      "Run subsetter N times (default: 1)", "N"},
-    {"set-overlaps-flag", 0, 0, G_OPTION_ARG_NONE,  &this->input->overlaps_flag,
+    {"set-overlaps-flag", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_SET_OVERLAPS_FLAG),
      "Set the overlaps flag on each glyph.",   nullptr},
-    {"notdef-outline", 0, 0, G_OPTION_ARG_NONE,  &this->input->notdef_outline,   "Keep the outline of \'.notdef\' glyph",   nullptr},
-    {"no-prune-unicode-ranges", 0, 0, G_OPTION_ARG_NONE,  &this->input->no_prune_unicode_ranges,   "Don't change the 'OS/2 ulUnicodeRange*' bits.",   nullptr},
-    {"glyph-names", 0, 0, G_OPTION_ARG_NONE,  &this->input->glyph_names,   "Keep PS glyph names in TT-flavored fonts. ",   nullptr},
+    {"notdef-outline", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_NOTDEF_OUTLINE),   "Keep the outline of \'.notdef\' glyph",   nullptr},
+    {"no-prune-unicode-ranges", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES),   "Don't change the 'OS/2 ulUnicodeRange*' bits.",   nullptr},
+    {"glyph-names", 0, 0, G_OPTION_ARG_NONE,  this->bool_for (HB_SUBSET_FLAGS_GLYPH_NAMES),   "Keep PS glyph names in TT-flavored fonts. ",   nullptr},
     {nullptr}
   };
   parser->add_group (entries,
diff --git a/util/options.hh b/util/options.hh
index 4e2303d..926f199 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -705,7 +705,31 @@
 
   void add_options (option_parser_t *parser) override;
 
+  hb_bool_t* bool_for(hb_subset_flags_t flag)
+  {
+    for (unsigned i = 0; i < sizeof(int) * 8; i++)
+    {
+      if (1 << i == flag)
+        return &flags[i];
+    }
+    return &flags[sizeof(int) * 8 - 1];
+  }
+
   unsigned num_iterations;
+
+  hb_subset_input_t * get_input ()
+  {
+    for (unsigned i = 0; i < sizeof(int) * 8; i++)
+    {
+      hb_subset_input_set_flags (input,
+                                 (hb_subset_flags_t) (1 << i),
+                                 flags[i] ? HB_SUBSET_FLAGS_ALL : HB_SUBSET_FLAGS_NONE);
+    }
+    return input;
+  }
+
+  hb_bool_t flags[sizeof(int) * 8] = {0};
+
   hb_subset_input_t *input;
 };