Add script and language public getter API
authorBehdad Esfahbod <behdad@behdad.org>
Mon, 28 Jan 2008 10:58:50 +0000 (05:58 -0500)
committerBehdad Esfahbod <behdad@behdad.org>
Mon, 28 Jan 2008 10:58:50 +0000 (05:58 -0500)
src/hb-ot-layout-open-private.h
src/hb-ot-layout.cc
src/hb-ot-layout.h
src/main.cc

index 95adfa5..3127c4d 100644 (file)
@@ -34,6 +34,8 @@
 #include "hb-ot-layout-private.h"
 
 
+#define NO_INDEX               ((unsigned int) 0xFFFF)
+
 /*
  * Int types
  */
 
 #define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \
   DEFINE_ARRAY_INTERFACE (Type, name); \
-  inline hb_tag_t get_##name##_tag (unsigned int i) const { \
+  inline const Tag& get_##name##_tag (unsigned int i) const { \
     return (*this)[i].tag; \
   }
 #define DEFINE_TAG_LIST_INTERFACE(Type, name) \
   }
 
 #define DEFINE_TAG_FIND_INTERFACE(Type, name) \
-  inline const Type* find_##name (hb_tag_t tag) const { \
-    for (unsigned int i = 0; i < get_##name##_count (); i++) \
-      if (tag == get_##name##_tag (i)) \
-        return &get_##name (i); \
-    return NULL; \
+  inline bool find_##name##_index (hb_tag_t tag, unsigned int *name##_index) const { \
+    const Tag t = tag; \
+    for (unsigned int i = 0; i < get_##name##_count (); i++) { \
+      if (t == get_##name##_tag (i)) { \
+        if (name##_index) *name##_index = i; \
+        return true; \
+      } \
+    } \
+    if (name##_index) *name##_index = NO_INDEX; \
+    return false; \
   } \
   inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \
-    const Type* res = find_##name (tag); \
-    if (res) \
-      return *res; \
+    unsigned int i; \
+    if (find_##name##_index (tag, &i)) \
+      return get_##name (i); \
     else \
       return Null##Type; \
   }
@@ -390,7 +397,7 @@ typedef struct OffsetTable {
   friend struct TTCHeader;
 
   DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table);   /* get_table_count(), get_table(i), get_table_tag(i) */
-  DEFINE_TAG_FIND_INTERFACE  (OpenTypeTable, table);   /* find_table(tag), get_table_by_tag(tag) */
+  DEFINE_TAG_FIND_INTERFACE  (OpenTypeTable, table);   /* find_table_index(tag), get_table_by_tag(tag) */
 
   private:
   /* OpenTypeTables, in no particular order */
@@ -509,10 +516,13 @@ struct LangSys {
 
   DEFINE_INDEX_ARRAY_INTERFACE (feature);
 
-  /* Returns -1 if none */
+  inline const bool has_required_feature (void) const {
+    return reqFeatureIndex != 0xffff;
+  }
+  /* Returns NO_INDEX if none */
   inline int get_required_feature_index (void) const {
     if (reqFeatureIndex == 0xffff)
-      return -1;
+      return NO_INDEX;
     return reqFeatureIndex;;
   }
 
@@ -543,7 +553,7 @@ struct Script {
   }
 
   /* TODO bsearch */
-  DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys);       /* find_lang_sys (), get_lang_sys_by_tag (tag) */
+  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 {
     return defaultLangSys != 0;
@@ -940,8 +950,8 @@ typedef struct GSUBGPOS {
   DEFINE_LIST_INTERFACE     (Lookup,  lookup );        /* get_lookup_count (), get_lookup (i) */
 
   /* TODO bsearch */
-  DEFINE_TAG_FIND_INTERFACE (Script,  script );        /* find_script (), get_script_by_tag (tag) */
-  DEFINE_TAG_FIND_INTERFACE (Feature, feature);        /* find_feature(), get_feature_by_tag(tag) */
+  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) */
 
   private:
   DEFINE_LIST_ARRAY(Script,  script);
index 4cd70de..33bfe42 100644 (file)
@@ -43,7 +43,7 @@
 struct _hb_ot_layout_t {
   const GDEF *gdef;
   const GSUB *gsub;
-//const GPOS *gpos;
+  const /*XXX*/GSUBGPOS *gpos;
 
   struct {
     unsigned char *klasses;
@@ -63,7 +63,7 @@ hb_ot_layout_create_for_data (const char *font_data,
 
   layout->gdef = &GDEF::get_for_data (font.get_table_data (face.get_table_by_tag (GDEF::Tag)));
   layout->gsub = &GSUB::get_for_data (font.get_table_data (face.get_table_by_tag (GSUB::Tag)));
-//layout->gpos = &GPOS::get_for_data (font.get_table_data (face.get_table_by_tag (GPOS::Tag)));
+  layout->gpos = &/*XXX*/GSUBGPOS::get_for_data (font.get_table_data (face.get_table_by_tag (/*XXX*/GSUBGPOS::GPOSTag)));
 
   return layout;
 }
@@ -243,3 +243,126 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
   for (i = 0; i < count; i++)
     hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
 }
+
+/*
+ * GSUB/GPOS
+ */
+
+static const GSUBGPOS&
+get_gsubgpos_table (hb_ot_layout_t            *layout,
+                   hb_ot_layout_table_type_t  table_type)
+{
+  switch (table_type) {
+    case HB_OT_LAYOUT_TABLE_TYPE_GSUB: return *(layout->gsub);
+    case HB_OT_LAYOUT_TABLE_TYPE_GPOS: return *(layout->gpos);
+    default:                           return NullGSUBGPOS;
+  }
+}
+
+
+unsigned int
+hb_ot_layout_get_script_count (hb_ot_layout_t            *layout,
+                              hb_ot_layout_table_type_t  table_type)
+{
+  const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
+
+  return g.get_script_count ();
+}
+
+hb_tag_t
+hb_ot_layout_get_script_tag (hb_ot_layout_t            *layout,
+                            hb_ot_layout_table_type_t  table_type,
+                            unsigned int               script_index)
+{
+  const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
+
+  return g.get_script_tag (script_index);
+}
+
+hb_bool_t
+hb_ot_layout_find_script (hb_ot_layout_t            *layout,
+                         hb_ot_layout_table_type_t  table_type,
+                         hb_tag_t                   script_tag,
+                         unsigned int              *script_index)
+{
+  unsigned int i;
+  const GSUBGPOS &g = get_gsubgpos_table (layout, table_type);
+
+  if (g.find_script_index (script_tag, script_index))
+    return TRUE;
+
+  /* try finding 'DFLT' */
+  if (g.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_SCRIPT, script_index))
+    return FALSE;
+
+  /* try with 'dflt'; MS site has had typos and many fonts use it now :( */
+  if (g.find_script_index (HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE, script_index))
+    return FALSE;
+
+  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  return FALSE;
+}
+
+
+unsigned int
+hb_ot_layout_get_language_count (hb_ot_layout_t            *layout,
+                                hb_ot_layout_table_type_t  table_type,
+                                unsigned int               script_index)
+{
+  const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index);
+
+  return s.get_lang_sys_count ();
+}
+
+hb_tag_t
+hb_ot_layout_get_language_tag (hb_ot_layout_t            *layout,
+                              hb_ot_layout_table_type_t  table_type,
+                              unsigned int               script_index,
+                              unsigned int               language_index)
+{
+  const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index);
+
+  return s.get_lang_sys_tag (language_index);
+}
+
+hb_bool_t
+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 i;
+  const Script &s = get_gsubgpos_table (layout, table_type).get_script (script_index);
+
+#if 0
+  if (s.find_script_index (script_tag, script_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))
+    return FALSE;
+
+  ////////////////////////
+  if (script_index) *script_index = HB_OT_LAYOUT_NO_SCRIPT_INDEX;
+  return FALSE;
+
+  if (language_index)
+    *language_index = PANGO_OT_DEFAULT_LANGUAGE;
+  if (required_feature_index)
+    *required_feature_index = PANGO_OT_NO_FEATURE;
+
+  if (script_index == PANGO_OT_NO_SCRIPT)
+    return FALSE;
+
+
+  /* DefaultLangSys */
+  if (language_index)
+    *language_index = PANGO_OT_DEFAULT_LANGUAGE;
+  if (required_feature_index)
+    *required_feature_index = script->DefaultLangSys.ReqFeatureIndex;
+#endif
+
+  return FALSE;
+}
index c515d5b..abea248 100644 (file)
@@ -78,6 +78,62 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
                                  unsigned char  *klasses,
                                  uint16_t        count);
 
+/*
+ * GSUB/GPOS
+ */
+
+typedef enum {
+  HB_OT_LAYOUT_TABLE_TYPE_GSUB,
+  HB_OT_LAYOUT_TABLE_TYPE_GPOS,
+  HB_OT_LAYOUT_TABLE_TYPE_NONE
+} hb_ot_layout_table_type_t;
+
+#define HB_OT_LAYOUT_NO_SCRIPT_INDEX           ((unsigned int) 0xFFFF)
+#define HB_OT_LAYOUT_NO_FEATURE_INDEX          ((unsigned int) 0xFFFF)
+#define HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX    ((unsigned int) 0xFFFF)
+#define HB_OT_LAYOUT_TAG_DEFAULT_SCRIPT                HB_TAG ('D', 'F', 'L', 'T')
+#define HB_OT_LAYOUT_TAG_DEFAULT_LANGUAGE      HB_TAG ('d', 'f', 'l', 't')
+
+unsigned int
+hb_ot_layout_get_script_count (hb_ot_layout_t            *layout,
+                              hb_ot_layout_table_type_t  table_type);
+
+hb_tag_t
+hb_ot_layout_get_script_tag (hb_ot_layout_t            *layout,
+                            hb_ot_layout_table_type_t  table_type,
+                            unsigned int               script_index);
+
+hb_bool_t
+hb_ot_layout_find_script (hb_ot_layout_t            *layout,
+                         hb_ot_layout_table_type_t  table_type,
+                         hb_tag_t                   script_tag,
+                         unsigned int              *script_index);
+
+unsigned int
+hb_ot_layout_get_language_count (hb_ot_layout_t            *layout,
+                                hb_ot_layout_table_type_t  table_type,
+                                unsigned int               script_index);
+
+hb_tag_t
+hb_ot_layout_get_language_tag (hb_ot_layout_t            *layout,
+                              hb_ot_layout_table_type_t  table_type,
+                              unsigned int               script_index,
+                              unsigned int               language_index);
+
+hb_bool_t
+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);
+
+
+/*
+#define PANGO_OT_ALL_GLYPHS                    ((guint) 0xFFFF)
+
+*/
+
 HB_END_DECLS();
 
 #endif /* HB_OT_LAYOUT_H */
index 1a81ad1..b149e11 100644 (file)
@@ -103,7 +103,7 @@ main (int argc, char **argv)
                   ? "      Default Language System\n"
                   : "      Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
                    (const char *)script.get_lang_sys_tag (n_langsys));
-           if (!langsys.get_required_feature_index ())
+           if (langsys.get_required_feature_index () == NO_INDEX)
              printf ("        No required feature\n");
 
            int num_features = langsys.get_feature_count ();