Imported Upstream version 2.3.1
[platform/upstream/harfbuzz.git] / src / hb-subset-plan.cc
index 55c4e3f..cff3426 100644 (file)
  * Google Author(s): Garret Rieger, Roderick Sheeter
  */
 
-#include "hb-map-private.hh"
-#include "hb-subset-private.hh"
-#include "hb-set-private.hh"
-
 #include "hb-subset-plan.hh"
+#include "hb-map.hh"
+#include "hb-set.hh"
+
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
+#include "hb-ot-cff1-table.hh"
 
 static void
 _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
@@ -54,29 +54,59 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
 }
 
 static void
+_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
+           hb_codepoint_t gid,
+           hb_set_t *gids_to_retain)
+{
+  hb_codepoint_t base_gid, accent_gid;
+  if (cff.get_seac_components (gid, &base_gid, &accent_gid))
+  {
+    hb_set_add (gids_to_retain, base_gid);
+    hb_set_add (gids_to_retain, accent_gid);
+  }
+}
+
+static void
 _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
 {
-  // TODO(grieger): This uses all lookups, instead collect
-  //                the set of lookups that are relevant.
-  //                See fontTools implementation.
+  hb_set_t lookup_indices;
+  hb_ot_layout_collect_lookups (face,
+                               HB_OT_TAG_GSUB,
+                               nullptr,
+                               nullptr,
+                               nullptr,
+                               &lookup_indices);
   hb_ot_layout_lookups_substitute_closure (face,
-                                           nullptr,
-                                           gids_to_retain);
+                                          &lookup_indices,
+                                          gids_to_retain);
 }
 
-
 static void
+_remove_invalid_gids (hb_set_t *glyphs,
+                     unsigned int num_glyphs)
+{
+  hb_codepoint_t gid = HB_SET_VALUE_INVALID;
+  while (glyphs->next (&gid))
+  {
+    if (gid >= num_glyphs)
+      glyphs->del (gid);
+  }
+}
+
+static hb_set_t *
 _populate_gids_to_retain (hb_face_t *face,
-                          const hb_set_t *unicodes,
-                          bool close_over_gsub,
-                          hb_set_t *unicodes_to_retain,
-                          hb_map_t *codepoint_to_glyph,
-                          hb_vector_t<hb_codepoint_t> *glyphs)
+                         const hb_set_t *unicodes,
+                         bool close_over_gsub,
+                         hb_set_t *unicodes_to_retain,
+                         hb_map_t *codepoint_to_glyph,
+                         hb_vector_t<hb_codepoint_t> *glyphs)
 {
   OT::cmap::accelerator_t cmap;
   OT::glyf::accelerator_t glyf;
+  OT::cff1::accelerator_t cff;
   cmap.init (face);
   glyf.init (face);
+  cff.init (face);
 
   hb_set_t *initial_gids_to_retain = hb_set_create ();
   initial_gids_to_retain->add (0); // Not-def
@@ -106,24 +136,30 @@ _populate_gids_to_retain (hb_face_t *face,
   while (initial_gids_to_retain->next (&gid))
   {
     _add_gid_and_children (glyf, gid, all_gids_to_retain);
+    if (cff.is_valid ())
+      _add_cff_seac_components (cff, gid, all_gids_to_retain);
   }
   hb_set_destroy (initial_gids_to_retain);
 
+  _remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
+
   glyphs->alloc (all_gids_to_retain->get_population ());
   gid = HB_SET_VALUE_INVALID;
   while (all_gids_to_retain->next (&gid))
     glyphs->push (gid);
 
-  hb_set_destroy (all_gids_to_retain);
+  cff.fini ();
   glyf.fini ();
   cmap.fini ();
+
+  return all_gids_to_retain;
 }
 
 static void
 _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
-                                hb_map_t *glyph_map)
+                               hb_map_t *glyph_map)
 {
-  for (unsigned int i = 0; i < glyphs.len; i++) {
+  for (unsigned int i = 0; i < glyphs.length; i++) {
     glyph_map->set (glyphs[i], i);
   }
 }
@@ -131,7 +167,7 @@ _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
 /**
  * hb_subset_plan_create:
  * Computes a plan for subsetting the supplied face according
- * to a provide profile and input. The plan describes
+ * to a provided input. The plan describes
  * which tables and glyphs should be retained.
  *
  * Return value: New subset plan.
@@ -140,28 +176,27 @@ _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
  **/
 hb_subset_plan_t *
 hb_subset_plan_create (hb_face_t           *face,
-                       hb_subset_profile_t *profile,
-                       hb_subset_input_t   *input)
+                      hb_subset_input_t   *input)
 {
   hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
 
   plan->drop_hints = input->drop_hints;
-  plan->drop_ot_layout = input->drop_ot_layout;
+  plan->drop_layout = input->drop_layout;
+  plan->desubroutinize = input->desubroutinize;
   plan->unicodes = hb_set_create();
   plan->glyphs.init();
   plan->source = hb_face_reference (face);
-  plan->dest = hb_subset_face_create ();
+  plan->dest = hb_face_builder_create ();
   plan->codepoint_to_glyph = hb_map_create();
   plan->glyph_map = hb_map_create();
-
-  _populate_gids_to_retain (face,
-                            input->unicodes,
-                            !plan->drop_ot_layout,
-                            plan->unicodes,
-                            plan->codepoint_to_glyph,
-                            &plan->glyphs);
+  plan->glyphset = _populate_gids_to_retain (face,
+                                            input->unicodes,
+                                            !plan->drop_layout,
+                                            plan->unicodes,
+                                            plan->codepoint_to_glyph,
+                                            &plan->glyphs);
   _create_old_gid_to_new_gid_map (plan->glyphs,
-                                  plan->glyph_map);
+                                 plan->glyph_map);
 
   return plan;
 }
@@ -177,11 +212,12 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
   if (!hb_object_destroy (plan)) return;
 
   hb_set_destroy (plan->unicodes);
-  plan->glyphs.fini();
+  plan->glyphs.fini ();
   hb_face_destroy (plan->source);
   hb_face_destroy (plan->dest);
   hb_map_destroy (plan->codepoint_to_glyph);
   hb_map_destroy (plan->glyph_map);
+  hb_set_destroy (plan->glyphset);
 
   free (plan);
 }