Finish script, language, and feature public API
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 28 Jan 2008 12:40:10 +0000 (07:40 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Tue, 29 Jan 2008 22:42:11 +0000 (17:42 -0500)
src/hb-ot-layout-open-private.h
src/hb-ot-layout.cc
src/hb-ot-layout.h

index 3127c4d..ce629db 100644 (file)
     if (HB_UNLIKELY (i >= num)) return NullTag; \
     return array[i].tag; \
   }
-  /* TODO: implement bsearch find_tag() and use it */
 
 
 #define DEFINE_ARRAY_INTERFACE(Type, name) \
   }
 #define DEFINE_INDEX_ARRAY_INTERFACE(name) \
   inline unsigned int get_##name##_index (unsigned int i) const { \
+    if (HB_UNLIKELY (i >= get_len ())) return NO_INDEX; \
     return (*this)[i]; \
   } \
   inline unsigned int get_##name##_count (void) const { \
-    return this->get_len (); \
+    return get_len (); \
   }
 
 
   private: inline Type() {} /* cannot be instantiated */ \
   public:
 
-/* TODO use a global nul-array for most Null's */
+// TODO use a global nul-array for most Null's
 /* defines Null##Type as a safe nil instance of Type */
 #define DEFINE_NULL_DATA(Type, size, data) \
   static const unsigned char Null##Type##Data[size] = data; \
@@ -546,13 +546,21 @@ DEFINE_NULL_ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF");
 
 struct Script {
 
-  DEFINE_ARRAY_INTERFACE (LangSys, lang_sys);  /* get_lang_sys_count(), get_lang_sys(i) */
+  /* DEFINE_ARRAY_INTERFACE (LangSys, lang_sys) but handling defaultLangSys */
+
+  inline const LangSys& get_lang_sys (unsigned int i) const {
+    if (i == NO_INDEX) return get_default_lang_sys ();
+    return (*this)[i];
+  }
+  inline unsigned int get_lang_sys_count (void) const {
+    return this->get_len ();
+  }
 
   inline const Tag& get_lang_sys_tag (unsigned int i) const {
     return get_tag (i);
   }
 
-  /* TODO bsearch */
+  // LONGTERMTODO bsearch
   DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys);       /* find_lang_sys_index (), get_lang_sys_by_tag (tag) */
 
   inline const bool has_default_lang_sys (void) const {
@@ -595,7 +603,7 @@ DEFINE_NULL_ASSERT_SIZE (ScriptList, 2);
 
 struct Feature {
 
-  DEFINE_INDEX_ARRAY_INTERFACE (lookup);
+  DEFINE_INDEX_ARRAY_INTERFACE (lookup);       /* get_feature_count(), get_feature_index(i) */
 
   private:
   /* LookupList indices, in no particular order */
@@ -949,7 +957,7 @@ typedef struct GSUBGPOS {
   DEFINE_TAG_LIST_INTERFACE (Feature, feature);        /* get_feature_count(), get_feature(i), get_feature_tag(i) */
   DEFINE_LIST_INTERFACE     (Lookup,  lookup );        /* get_lookup_count (), get_lookup (i) */
 
-  /* TODO bsearch */
+  // LONGTERMTODO bsearch
   DEFINE_TAG_FIND_INTERFACE (Script,  script );        /* find_script_index (), get_script_by_tag (tag) */
   DEFINE_TAG_FIND_INTERFACE (Feature, feature);        /* find_feature_index(), get_feature_by_tag(tag) */
 
index 33bfe42..22fa81c 100644 (file)
@@ -53,10 +53,27 @@ struct _hb_ot_layout_t {
 };
 
 hb_ot_layout_t *
+hb_ot_layout_create (void)
+{
+  hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+
+  layout->gdef = &NullGDEF;
+  layout->gsub = &NullGSUB;
+  layout->gpos = &/*XXX*/NullGSUBGPOS;
+
+  return layout;
+}
+
+hb_ot_layout_t *
 hb_ot_layout_create_for_data (const char *font_data,
                              int         face_index)
 {
-  hb_ot_layout_t *layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
+  hb_ot_layout_t *layout;
+
+  if (HB_UNLIKELY (font_data == NULL))
+    return hb_ot_layout_create ();
+
+  layout = (hb_ot_layout_t *) calloc (1, sizeof (hb_ot_layout_t));
 
   const OpenTypeFontFile &font = OpenTypeFontFile::get_for_data (font_data);
   const OpenTypeFontFace &face = font.get_face (face_index);
@@ -285,7 +302,7 @@ hb_ot_layout_find_script (hb_ot_layout_t            *layout,
                          hb_tag_t                   script_tag,
                          unsigned int              *script_index)
 {
-  unsigned int i;
+  ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX);
   const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
 
   if (g.find_script_index (script_tag, script_index))
@@ -330,39 +347,85 @@ hb_ot_layout_find_language (hb_ot_layout_t            *layout,
                            hb_ot_layout_table_type_t  table_type,
                            unsigned int               script_index,
                            hb_tag_t                   language_tag,
-                           unsigned int              *language_index,
-                           unsigned int              *required_features_index)
+                           unsigned int              *language_index)
 {
-  unsigned int i;
+  ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX);
   const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index);
 
-#if 0
-  if (s.find_script_index (script_tag, script_index))
+  if (s.find_lang_sys_index (language_tag, language_index))
     return TRUE;
 
   /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
-  if (s.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, script_index))
+  if (s.find_lang_sys_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, language_index))
     return FALSE;
 
-  ////////////////////////
-  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
   return FALSE;
+}
 
-  if (language_index)
-    *language_index = PANGO_OT_DEFAULT_LANGUAGE;
-  if (required_feature_index)
-    *required_feature_index = PANGO_OT_NO_FEATURE;
+hb_bool_t
+hb_ot_layout_get_required_feature_index (hb_ot_layout_t            *layout,
+                                        hb_ot_layout_table_type_t  table_type,
+                                        unsigned int               script_index,
+                                        unsigned int               language_index,
+                                        unsigned int              *feature_index)
+{
+  const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index);
 
-  if (script_index == PANGO_OT_NO_SCRIPT)
-    return FALSE;
+  if (feature_index) *feature_index = l.get_required_feature_index ();
 
+  return l.has_required_feature ();
+}
 
-  /* DefaultLangSys */
-  if (language_index)
-    *language_index = PANGO_OT_DEFAULT_LANGUAGE;
-  if (required_feature_index)
-    *required_feature_index = script->DefaultLangSys.ReqFeatureIndex;
-#endif
+unsigned int
+hb_ot_layout_get_feature_count (hb_ot_layout_t            *layout,
+                               hb_ot_layout_table_type_t  table_type,
+                               unsigned int               script_index,
+                               unsigned int               language_index)
+{
+  const LangSys &l = get_gsubgpos_table (layout, table_type).get_script (script_index).get_lang_sys (language_index);
+
+  return l.get_feature_count ();
+}
+
+hb_tag_t
+hb_ot_layout_get_feature_tag (hb_ot_layout_t            *layout,
+                             hb_ot_layout_table_type_t  table_type,
+                             unsigned int               script_index,
+                             unsigned int               language_index,
+                             unsigned int               feature_index)
+{
+  const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
+  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  feature_index = l.get_feature_index (feature_index);
+
+  return g.get_feature_tag (feature_index);
+}
+
+
+hb_bool_t
+hb_ot_layout_find_feature (hb_ot_layout_t            *layout,
+                          hb_ot_layout_table_type_t  table_type,
+                          unsigned int               script_index,
+                          unsigned int               language_index,
+                          hb_tag_t                   feature_tag,
+                          unsigned int              *feature_index)
+{
+  ASSERT_STATIC (NO_INDEX == HB_OT_LAYOUT_NO_FEATURE_INDEX);
+  const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
+  const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+  unsigned int i;
+
+  for (i = 0; i < l.get_feature_count (); i++) {
+    unsigned int f_index = l.get_feature_index (i);
+
+    if (feature_tag == g.get_feature_tag (f_index)) {
+      if (feature_index) *feature_index = f_index;
+      return TRUE;
+    }
+  }
 
+  if (feature_index) *feature_index = HB_OT_LAYOUT_NO_FEATURE_INDEX;
   return FALSE;
 }
index abea248..895cc44 100644 (file)
@@ -38,6 +38,9 @@ HB_BEGIN_DECLS();
 typedef struct _hb_ot_layout_t hb_ot_layout_t;
 
 hb_ot_layout_t *
+hb_ot_layout_create (void);
+
+hb_ot_layout_t *
 hb_ot_layout_create_for_data (const char *font_data,
                              int         face_index);
 
@@ -125,8 +128,35 @@ hb_ot_layout_find_language (hb_ot_layout_t            *layout,
                            hb_ot_layout_table_type_t  table_type,
                            unsigned int               script_index,
                            hb_tag_t                   language_tag,
-                           unsigned int              *language_index,
-                           unsigned int              *required_features_index);
+                           unsigned int              *language_index);
+
+hb_bool_t
+hb_ot_layout_get_required_feature_index (hb_ot_layout_t            *layout,
+                                        hb_ot_layout_table_type_t  table_type,
+                                        unsigned int               script_index,
+                                        unsigned int               language_index,
+                                        unsigned int              *feature_index);
+
+unsigned int
+hb_ot_layout_get_feature_count (hb_ot_layout_t            *layout,
+                               hb_ot_layout_table_type_t  table_type,
+                               unsigned int               script_index,
+                               unsigned int               language_index);
+
+hb_tag_t
+hb_ot_layout_get_feature_tag (hb_ot_layout_t            *layout,
+                             hb_ot_layout_table_type_t  table_type,
+                             unsigned int               script_index,
+                             unsigned int               language_index,
+                             unsigned int               feature_index);
+
+hb_bool_t
+hb_ot_layout_find_feature (hb_ot_layout_t            *layout,
+                          hb_ot_layout_table_type_t  table_type,
+                          unsigned int               script_index,
+                          unsigned int               language_index,
+                          hb_tag_t                   feature_tag,
+                          unsigned int              *feature_index);
 
 
 /*