[pango] [HB] Remove clumsy macros and improve API



commit c899bfddd1aaa0f0b4242910080f80a9889cb27c
Author: Behdad Esfahbod <behdad behdad org>
Date:   Fri Aug 7 19:46:30 2009 -0400

    [HB] Remove clumsy macros and improve API

 pango/opentype/TODO                             |    2 -
 pango/opentype/hb-open-file-private.hh          |   41 ++++++-
 pango/opentype/hb-open-type-private.hh          |  104 +----------------
 pango/opentype/hb-ot-layout-common-private.hh   |  103 ++++++++++++----
 pango/opentype/hb-ot-layout-gsubgpos-private.hh |   35 +++++-
 pango/opentype/hb-ot-layout.cc                  |  146 ++++++++---------------
 pango/opentype/hb-ot-layout.h                   |  101 +++++++---------
 pango/pango-ot-info.c                           |   96 ++++++----------
 8 files changed, 274 insertions(+), 354 deletions(-)
---
diff --git a/pango/opentype/TODO b/pango/opentype/TODO
index b753c29..2b22970 100644
--- a/pango/opentype/TODO
+++ b/pango/opentype/TODO
@@ -4,6 +4,4 @@
 - Rename LookupFlag::MarkAttachmentType to LookupFlag:IgnoreSpecialMarks
 - cmap14 support in get_glyph callback
 - size_t?
-- change get_XXX_count / get_XXX_tag to be more like
-  hb_ot_layout_get_lig_carets (IN/OUT)?
 - Figure out compiler selection (add test for link to libstdc++)
diff --git a/pango/opentype/hb-open-file-private.hh b/pango/opentype/hb-open-file-private.hh
index ee7dc60..7d2ab20 100644
--- a/pango/opentype/hb-open-file-private.hh
+++ b/pango/opentype/hb-open-file-private.hh
@@ -67,14 +67,43 @@ typedef struct OffsetTable
   friend struct TTCHeader;
 
   STATIC_DEFINE_GET_FOR_DATA (OffsetTable);
-  DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table);	/* get_table_count(), get_table(i), get_table_tag(i) */
-  DEFINE_TAG_FIND_INTERFACE  (OpenTypeTable, table);	/* find_table_index(tag), get_table_by_tag(tag) */
 
-  unsigned int get_face_count (void) const { return 1; }
+  inline unsigned int get_table_count (void) const
+  { return numTables; }
+  inline const Tag& get_table_tag (unsigned int i) const
+  {
+    if (HB_UNLIKELY (i >= numTables)) return Null(Tag);
+    return tableDir[i].tag;
+  }
+  inline const TableDirectory& get_table (unsigned int i) const
+  {
+    if (HB_UNLIKELY (i >= numTables)) return Null(TableDirectory);
+    return tableDir[i];
+  }
+  inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
+  {
+    const Tag t = tag;
+    // TODO bsearch
+    unsigned int count = numTables;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (t == tableDir[i].tag)
+      {
+        if (table_index) *table_index = i;
+        return true;
+      }
+    }
+    if (table_index) *table_index = NO_INDEX;
+    return false;
+  }
+  inline const TableDirectory& get_table_by_tag (hb_tag_t tag) const
+  {
+    unsigned int table_index;
+    find_table_index (tag, &table_index);
+    return get_table (table_index);
+  }
 
-  private:
-  /* OpenTypeTables, in no particular order */
-  DEFINE_ARRAY_TYPE (TableDirectory, tableDir, numTables);
+  unsigned int get_face_count (void) const { return 1; }
 
   public:
   inline bool sanitize (SANITIZE_ARG_DEF, const void *base) {
diff --git a/pango/opentype/hb-open-type-private.hh b/pango/opentype/hb-open-type-private.hh
index 494a99d..26c1cac 100644
--- a/pango/opentype/hb-open-type-private.hh
+++ b/pango/opentype/hb-open-type-private.hh
@@ -52,99 +52,6 @@
 
 
 /*
- * Array types
- */
-
-/* get_len() is a method returning the number of items in an array-like object */
-#define DEFINE_LEN(Type, array, num) \
-  inline unsigned int get_len(void) const { return num; } \
-
-/* An array type is one that contains a variable number of objects
- * as its last item.  An array object is extended with get_len()
- * methods, as well as overloaded [] operator. */
-#define DEFINE_ARRAY_TYPE(Type, array, num) \
-  DEFINE_INDEX_OPERATOR(Type, array, num) \
-  DEFINE_LEN(Type, array, num)
-#define DEFINE_INDEX_OPERATOR(Type, array, num) \
-  inline const Type& operator[] (unsigned int i) const \
-  { \
-    if (HB_UNLIKELY (i >= num)) return Null(Type); \
-    return array[i]; \
-  }
-
-/* An offset array type is like an array type, but it contains a table
- * of offsets to the objects, relative to the beginning of the current
- * object. */
-#define DEFINE_OFFSET_ARRAY_TYPE(Type, array, num) \
-  DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \
-  DEFINE_LEN(Offset, array, num)
-#define DEFINE_OFFSET_INDEX_OPERATOR(Type, array, num) \
-  inline const Type& operator[] (unsigned int i) const \
-  { \
-    if (HB_UNLIKELY (i >= num)) return Null(Type); \
-    if (HB_UNLIKELY (!array[i])) return Null(Type); \
-    return *(const Type)((const char*)this + array[i]); \
-  }
-
-
-#define DEFINE_ARRAY_INTERFACE(Type, name) \
-  inline const Type& get_##name (unsigned int i) const { return (*this)[i]; } \
-  inline unsigned int get_##name##_count (void) const { return this->get_len (); }
-#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 get_len (); }
-
-
-/*
- * List types
- */
-
-#define DEFINE_LIST_INTERFACE(Type, name) \
-  inline const Type& get_##name (unsigned int i) const { return (this+name##List)[i]; } \
-  inline unsigned int get_##name##_count (void) const { return (this+name##List).len; }
-
-
-/*
- * Tag types
- */
-
-#define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \
-  DEFINE_ARRAY_INTERFACE (Type, name); \
-  inline const Tag& get_##name##_tag (unsigned int i) const { return (*this)[i].tag; }
-#define DEFINE_TAG_LIST_INTERFACE(Type, name) \
-  DEFINE_LIST_INTERFACE (Type, name); \
-  inline const Tag& get_##name##_tag (unsigned int i) const { return (this+name##List).get_tag (i); }
-
-#define DEFINE_TAG_FIND_INTERFACE(Type, name) \
-  inline bool find_##name##_index (hb_tag_t tag, unsigned int *index) const { \
-    const Tag t = tag; \
-    for (unsigned int i = 0; i < get_##name##_count (); i++) \
-    { \
-      if (t == get_##name##_tag (i)) \
-      { \
-        if (index) *index = i; \
-        return true; \
-      } \
-    } \
-    if (index) *index = NO_INDEX; \
-    return false; \
-  } \
-  inline const Type& get_##name##_by_tag (hb_tag_t tag) const \
-  { \
-    unsigned int i; \
-    if (find_##name##_index (tag, &i)) \
-      return get_##name (i); \
-    else \
-      return Null(Type); \
-  }
-
-
-
-/*
  * Class features
  */
 
@@ -379,13 +286,7 @@ struct Sanitizer
 
 /*
  *
- * The OpenType Font File
- *
- */
-
-
-/*
- * Data Types
+ * The OpenType Font File: Data Types
  */
 
 
@@ -433,6 +334,7 @@ DEFINE_INT_TYPE (SHORT,	  , 16);	/* 16-bit signed integer. */
 DEFINE_INT_TYPE (ULONG,	 u, 32);	/* 32-bit unsigned integer. */
 DEFINE_INT_TYPE (LONG,	  , 32);	/* 32-bit signed integer. */
 
+
 /* Array of four uint8s (length = 32 bits) used to identify a script, language
  * system, feature, or baseline */
 struct Tag : ULONG
@@ -550,6 +452,8 @@ struct OffsetTo : GenericOffsetTo<Offset, Type> {};
 
 template <typename Type>
 struct LongOffsetTo : GenericOffsetTo<LongOffset, Type> {};
+
+
 /*
  * Array Types
  */
diff --git a/pango/opentype/hb-ot-layout-common-private.hh b/pango/opentype/hb-ot-layout-common-private.hh
index 75ef787..9a6ccdc 100644
--- a/pango/opentype/hb-ot-layout-common-private.hh
+++ b/pango/opentype/hb-ot-layout-common-private.hh
@@ -58,21 +58,45 @@ struct Record
 };
 
 template <typename Type>
-struct RecordArrayOf : ArrayOf<Record<Type> > {};
-
-template <typename Type>
-struct RecordListOf : RecordArrayOf<Type>
-{
-  inline const Type& operator [] (unsigned int i) const
-  {
-    if (HB_UNLIKELY (i >= this->len)) return Null(Type);
-    return this+this->array[i].offset;
-  }
+struct RecordArrayOf : ArrayOf<Record<Type> > {
   inline const Tag& get_tag (unsigned int i) const
   {
     if (HB_UNLIKELY (i >= this->len)) return Null(Tag);
     return this->array[i].tag;
   }
+  inline bool get_tags (unsigned int *record_count /* IN/OUT */,
+			hb_tag_t     *record_tags /* OUT */) const
+  {
+    unsigned int count = MIN (this->len, *record_count);
+    for (unsigned int i = 0; i < count; i++)
+      record_tags[i] = this->array[i].tag;
+
+    *record_count = this->len;
+    return !!this->len;
+  }
+  inline bool find_index (hb_tag_t tag, unsigned int *index) const
+  {
+    const Tag t = tag;
+    // TODO bsearch
+    unsigned int count = this->len;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (t == this->array[i].tag)
+      {
+        if (index) *index = i;
+        return true;
+      }
+    }
+    if (index) *index = NO_INDEX;
+    return false;
+  }
+};
+
+template <typename Type>
+struct RecordListOf : RecordArrayOf<Type>
+{
+  inline const Type& operator [] (unsigned int i) const
+  { return this+RecordArrayOf<Type>::operator[](i).offset; }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
     SANITIZE_DEBUG ();
@@ -81,6 +105,27 @@ struct RecordListOf : RecordArrayOf<Type>
 };
 
 
+struct IndexArray : ArrayOf<USHORT>
+{
+  inline unsigned int operator [] (unsigned int i) const
+  {
+    if (HB_UNLIKELY (i >= this->len))
+      return NO_INDEX;
+    return this->array[i];
+  }
+  inline bool get_indexes (unsigned int *_count /* IN/OUT */,
+			   unsigned int *_indexes /* OUT */) const
+  {
+    unsigned int count = MIN (this->len, *_count);
+    for (unsigned int i = 0; i < count; i++)
+      _indexes[i] = this->array[i];
+
+    *_count = this->len;
+    return !!this->len;
+  }
+};
+
+
 struct Script;
 struct LangSys;
 struct Feature;
@@ -88,8 +133,13 @@ struct Feature;
 
 struct LangSys
 {
-  inline unsigned int get_feature_index (unsigned int i) const { return featureIndex[i]; }
-  inline unsigned int get_feature_count (void) const { return featureIndex.len; }
+  inline unsigned int get_feature_count (void) const
+  { return featureIndex.len; }
+  inline hb_tag_t get_feature_index (unsigned int i) const
+  { return featureIndex[i]; }
+  inline bool get_feature_indexes (unsigned int *feature_count /* IN/OUT */,
+				   hb_tag_t     *feature_tags /* OUT */) const
+  { return featureIndex.get_indexes (feature_count, feature_tags); }
 
   inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
   inline int get_required_feature_index (void) const
@@ -109,24 +159,27 @@ struct LangSys
   USHORT	reqFeatureIndex;/* Index of a feature required for this
 				 * language system--if no required features
 				 * = 0xFFFF */
-  ArrayOf<USHORT>
-		featureIndex;	/* Array of indices into the FeatureList */
+  IndexArray	featureIndex;	/* Array of indices into the FeatureList */
 };
 ASSERT_SIZE_DATA (LangSys, 6, "\0\0\xFF\xFF");
 
 
 struct Script
 {
+  inline unsigned int get_lang_sys_count (void) const
+  { return langSys.len; }
+  inline const Tag& get_lang_sys_tag (unsigned int i) const
+  { return langSys.get_tag (i); }
+  inline bool get_lang_sys_tags (unsigned int *lang_sys_count /* IN/OUT */,
+				 hb_tag_t     *lang_sys_tags /* OUT */) const
+  { return langSys.get_tags (lang_sys_count, lang_sys_tags); }
   inline const LangSys& get_lang_sys (unsigned int i) const
   {
     if (i == NO_INDEX) return get_default_lang_sys ();
     return this+langSys[i].offset;
   }
-  inline unsigned int get_lang_sys_count (void) const { return langSys.len; }
-  inline const Tag& get_lang_sys_tag (unsigned int i) const { return langSys[i].tag; }
-
-  // LONGTERMTODO bsearch
-  DEFINE_TAG_FIND_INTERFACE (LangSys, lang_sys);	/* find_lang_sys_index (), get_lang_sys_by_tag (tag) */
+  inline bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const
+  { return langSys.find_index (tag, index); }
 
   inline bool has_default_lang_sys (void) const { return defaultLangSys != 0; }
   inline const LangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
@@ -152,8 +205,13 @@ ASSERT_SIZE (ScriptList, 2);
 
 struct Feature
 {
-  inline unsigned int get_lookup_index (unsigned int i) const { return lookupIndex[i]; }
-  inline unsigned int get_lookup_count (void) const { return lookupIndex.len; }
+  inline unsigned int get_lookup_count (void) const
+  { return lookupIndex.len; }
+  inline hb_tag_t get_lookup_index (unsigned int i) const
+  { return lookupIndex[i]; }
+  inline bool get_lookup_indexes (unsigned int *lookup_count /* IN/OUT */,
+				  hb_tag_t     *lookup_tags /* OUT */) const
+  { return lookupIndex.get_indexes (lookup_count, lookup_tags); }
 
   inline bool sanitize (SANITIZE_ARG_DEF) {
     SANITIZE_DEBUG ();
@@ -166,8 +224,7 @@ struct Feature
 				 * has been defined for the feature), relative
 				 * to the beginning of the Feature Table; = Null
 				 * if not required */
-  ArrayOf<USHORT>
-		lookupIndex;	/* Array of LookupList indices */
+  IndexArray	 lookupIndex;	/* Array of LookupList indices */
 };
 ASSERT_SIZE (Feature, 4);
 
diff --git a/pango/opentype/hb-ot-layout-gsubgpos-private.hh b/pango/opentype/hb-ot-layout-gsubgpos-private.hh
index 63ae463..dcfaa91 100644
--- a/pango/opentype/hb-ot-layout-gsubgpos-private.hh
+++ b/pango/opentype/hb-ot-layout-gsubgpos-private.hh
@@ -855,13 +855,34 @@ struct GSUBGPOS
 
   STATIC_DEFINE_GET_FOR_DATA_CHECK_MAJOR_VERSION (GSUBGPOS, 1, 1);
 
-  DEFINE_TAG_LIST_INTERFACE (Script,  script );	/* get_script_count (), get_script (i), get_script_tag (i) */
-  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) */
-
-  // 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) */
+  inline unsigned int get_script_count (void) const
+  { return (this+scriptList).len; }
+  inline const Tag& get_script_tag (unsigned int i) const
+  { return (this+scriptList).get_tag (i); }
+  inline bool get_script_tags (unsigned int *script_count /* IN/OUT */,
+			       hb_tag_t     *script_tags /* OUT */) const
+  { return (this+scriptList).get_tags (script_count, script_tags); }
+  inline const Script& get_script (unsigned int i) const
+  { return (this+scriptList)[i]; }
+  inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
+  { return (this+scriptList).find_index (tag, index); }
+
+  inline unsigned int get_feature_count (void) const
+  { return (this+featureList).len; }
+  inline const Tag& get_feature_tag (unsigned int i) const
+  { return (this+featureList).get_tag (i); }
+  inline bool get_feature_tags (unsigned int *feature_count /* IN/OUT */,
+				hb_tag_t     *feature_tags /* OUT */) const
+  { return (this+featureList).get_tags (feature_count, feature_tags); }
+  inline const Feature& get_feature (unsigned int i) const
+  { return (this+featureList)[i]; }
+  inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const
+  { return (this+featureList).find_index (tag, index); }
+
+  inline unsigned int get_lookup_count (void) const
+  { return (this+lookupList).len; }
+  inline const Lookup& get_lookup (unsigned int i) const
+  { return (this+lookupList)[i]; }
 
   bool sanitize (SANITIZE_ARG_DEF) {
     SANITIZE_DEBUG ();
diff --git a/pango/opentype/hb-ot-layout.cc b/pango/opentype/hb-ot-layout.cc
index 95d08ac..b912a97 100644
--- a/pango/opentype/hb-ot-layout.cc
+++ b/pango/opentype/hb-ot-layout.cc
@@ -336,23 +336,15 @@ get_gsubgpos_table (hb_face_t *face,
 }
 
 
-unsigned int
-hb_ot_layout_table_get_script_count (hb_face_t *face,
-				     hb_tag_t   table_tag)
-{
-  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
-
-  return g.get_script_count ();
-}
-
-hb_tag_t
-hb_ot_layout_table_get_script_tag (hb_face_t    *face,
-				   hb_tag_t      table_tag,
-				   unsigned int  script_index)
+hb_bool_t
+hb_ot_layout_table_get_script_tags (hb_face_t    *face,
+				    hb_tag_t      table_tag,
+				    unsigned int *script_count /* IN/OUT */,
+				    hb_tag_t     *script_tags /* OUT */)
 {
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
-  return g.get_script_tag (script_index);
+  return g.get_script_tags (script_count, script_tags);
 }
 
 hb_bool_t
@@ -379,23 +371,15 @@ hb_ot_layout_table_find_script (hb_face_t    *face,
   return FALSE;
 }
 
-unsigned int
-hb_ot_layout_table_get_feature_count (hb_face_t *face,
-				      hb_tag_t   table_tag)
-{
-  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
-
-  return g.get_feature_count ();
-}
-
-hb_tag_t
-hb_ot_layout_table_get_feature_tag (hb_face_t    *face,
-				    hb_tag_t      table_tag,
-				    unsigned int  feature_index)
+hb_bool_t
+hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
+				     hb_tag_t      table_tag,
+				     unsigned int *feature_count /* IN/OUT */,
+				     hb_tag_t     *feature_tags /* OUT */)
 {
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
-  return g.get_feature_tag (feature_index);
+  return g.get_feature_tags (feature_count, feature_tags);
 }
 
 hb_bool_t
@@ -414,35 +398,17 @@ hb_ot_layout_table_find_feature (hb_face_t    *face,
   return FALSE;
 }
 
-unsigned int
-hb_ot_layout_table_get_lookup_count (hb_face_t *face,
-				     hb_tag_t   table_tag)
-{
-  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
 
-  return g.get_lookup_count ();
-}
-
-
-unsigned int
-hb_ot_layout_script_get_language_count (hb_face_t    *face,
-					hb_tag_t      table_tag,
-					unsigned int  script_index)
-{
-  const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
-
-  return s.get_lang_sys_count ();
-}
-
-hb_tag_t
-hb_ot_layout_script_get_language_tag (hb_face_t    *face,
-				      hb_tag_t      table_tag,
-				      unsigned int  script_index,
-				      unsigned int  language_index)
+hb_bool_t
+hb_ot_layout_script_get_language_tags (hb_face_t    *face,
+				       hb_tag_t      table_tag,
+				       unsigned int  script_index,
+				       unsigned int *language_count /* IN/OUT */,
+				       hb_tag_t     *language_tags /* OUT */)
 {
   const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
 
-  return s.get_lang_sys_tag (language_index);
+  return s.get_lang_sys_tags (language_count, language_tags);
 }
 
 hb_bool_t
@@ -480,42 +446,40 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
   return l.has_required_feature ();
 }
 
-unsigned int
-hb_ot_layout_language_get_feature_count (hb_face_t    *face,
-					 hb_tag_t      table_tag,
-					 unsigned int  script_index,
-					 unsigned int  language_index)
-{
-  const LangSys &l = get_gsubgpos_table (face, table_tag).get_script (script_index).get_lang_sys (language_index);
-
-  return l.get_feature_count ();
-}
-
-unsigned int
-hb_ot_layout_language_get_feature_index (hb_face_t    *face,
-					 hb_tag_t      table_tag,
-					 unsigned int  script_index,
-					 unsigned int  language_index,
-					 unsigned int  num_feature)
+hb_bool_t
+hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
+					   hb_tag_t      table_tag,
+					   unsigned int  script_index,
+					   unsigned int  language_index,
+					   unsigned int *feature_count /* IN/OUT */,
+					   unsigned int *feature_indexes /* OUT */)
 {
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
 
-  return l.get_feature_index (num_feature);
+  return l.get_feature_indexes (feature_count, feature_indexes);
 }
 
-hb_tag_t
-hb_ot_layout_language_get_feature_tag (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  script_index,
-				       unsigned int  language_index,
-				       unsigned int  num_feature)
+hb_bool_t
+hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
+					hb_tag_t      table_tag,
+					unsigned int  script_index,
+					unsigned int  language_index,
+					unsigned int *feature_count /* IN/OUT */,
+					hb_tag_t     *feature_tags /* OUT */)
 {
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
-  unsigned int feature_index = l.get_feature_index (num_feature);
 
-  return g.get_feature_tag (feature_index);
+  ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
+  unsigned int count = feature_count ? *feature_count : 0;
+  hb_bool_t ret = l.get_feature_indexes (feature_count, (unsigned int *) feature_tags);
+
+  count = feature_count ? MIN (count, *feature_count) : 0;
+  for (unsigned int i = 0; i < count; i++)
+    feature_tags[i] = g.get_feature_tag ((unsigned int) feature_tags[i]);
+
+  return ret;
 }
 
 
@@ -545,28 +509,19 @@ hb_ot_layout_language_find_feature (hb_face_t    *face,
   return FALSE;
 }
 
-unsigned int
-hb_ot_layout_feature_get_lookup_count (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  feature_index)
+hb_bool_t
+hb_ot_layout_feature_get_lookup_indexes (hb_face_t    *face,
+					 hb_tag_t      table_tag,
+					 unsigned int  feature_index,
+					 unsigned int *lookup_count /* IN/OUT */,
+					 unsigned int *lookup_indexes /* OUT */)
 {
   const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
   const Feature &f = g.get_feature (feature_index);
 
-  return f.get_lookup_count ();
+  return f.get_lookup_indexes (lookup_count, lookup_indexes);
 }
 
-unsigned int
-hb_ot_layout_feature_get_lookup_index (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  feature_index,
-				       unsigned int  num_lookup)
-{
-  const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
-  const Feature &f = g.get_feature (feature_index);
-
-  return f.get_lookup_index (num_lookup);
-}
 
 /*
  * GSUB
@@ -590,6 +545,7 @@ hb_ot_layout_substitute_lookup (hb_face_t                   *face,
   return _get_gsub (face).substitute_lookup (&context, buffer, lookup_index, mask);
 }
 
+
 /*
  * GPOS
  */
diff --git a/pango/opentype/hb-ot-layout.h b/pango/opentype/hb-ot-layout.h
index 889a2bd..04078d3 100644
--- a/pango/opentype/hb-ot-layout.h
+++ b/pango/opentype/hb-ot-layout.h
@@ -71,12 +71,15 @@ hb_ot_layout_build_glyph_classes (hb_face_t      *face,
 				unsigned char  *klasses,
 				uint16_t        count);
 
+/* Not that useful.  Provides list of attach points for a glyph that a
+ * client may want to cache */
 hb_bool_t
 hb_ot_layout_get_attach_points (hb_face_t      *face,
 				hb_codepoint_t  glyph,
 				unsigned int   *point_count /* IN/OUT */,
 				unsigned int   *point_array /* OUT */);
 
+/* Ligature caret positions */
 hb_bool_t
 hb_ot_layout_get_lig_carets (hb_face_t      *face,
 			     hb_font_t      *font,
@@ -84,8 +87,9 @@ hb_ot_layout_get_lig_carets (hb_face_t      *face,
 			     unsigned int   *caret_count /* IN/OUT */,
 			     int            *caret_array /* OUT */);
 
+
 /*
- * GSUB/GPOS
+ * GSUB/GPOS feature query and enumeration interface
  */
 
 typedef uint32_t hb_ot_layout_feature_mask_t;
@@ -96,14 +100,11 @@ typedef uint32_t hb_ot_layout_feature_mask_t;
 #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_table_get_script_count (hb_face_t *face,
-				     hb_tag_t   table_tag);
-
-hb_tag_t
-hb_ot_layout_table_get_script_tag (hb_face_t    *face,
-				   hb_tag_t      table_tag,
-				   unsigned int  script_index);
+hb_bool_t
+hb_ot_layout_table_get_script_tags (hb_face_t    *face,
+				    hb_tag_t      table_tag,
+				    unsigned int *script_count /* IN/OUT */,
+				    hb_tag_t     *script_tags /* OUT */);
 
 hb_bool_t
 hb_ot_layout_table_find_script (hb_face_t    *face,
@@ -111,14 +112,11 @@ hb_ot_layout_table_find_script (hb_face_t    *face,
 				hb_tag_t      script_tag,
 				unsigned int *script_index);
 
-unsigned int
-hb_ot_layout_table_get_feature_count (hb_face_t *face,
-				      hb_tag_t   table_tag);
-
-hb_tag_t
-hb_ot_layout_table_get_feature_tag (hb_face_t    *face,
-				    hb_tag_t      table_tag,
-				    unsigned int  feature_index);
+hb_bool_t
+hb_ot_layout_table_get_feature_tags (hb_face_t    *face,
+				     hb_tag_t      table_tag,
+				     unsigned int *feature_count /* IN/OUT */,
+				     hb_tag_t     *feature_tags /* OUT */);
 
 hb_bool_t
 hb_ot_layout_table_find_feature (hb_face_t    *face,
@@ -126,20 +124,12 @@ hb_ot_layout_table_find_feature (hb_face_t    *face,
 				 hb_tag_t      feature_tag,
 				 unsigned int *feature_index);
 
-unsigned int
-hb_ot_layout_table_get_lookup_count (hb_face_t  *face,
-				     hb_tag_t    table_tag);
-
-unsigned int
-hb_ot_layout_script_get_language_count (hb_face_t    *face,
-					hb_tag_t      table_tag,
-					unsigned int  script_index);
-
-hb_tag_t
-hb_ot_layout_script_get_language_tag (hb_face_t    *face,
-				      hb_tag_t      table_tag,
-				      unsigned int  script_index,
-				      unsigned int  language_index);
+hb_bool_t
+hb_ot_layout_script_get_language_tags (hb_face_t    *face,
+				       hb_tag_t      table_tag,
+				       unsigned int  script_index,
+				       unsigned int *language_count /* IN/OUT */,
+				       hb_tag_t     *language_tags /* OUT */);
 
 hb_bool_t
 hb_ot_layout_script_find_language (hb_face_t    *face,
@@ -155,25 +145,21 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t    *face,
 						  unsigned int  language_index,
 						  unsigned int *feature_index);
 
-unsigned int
-hb_ot_layout_language_get_feature_count (hb_face_t    *face,
-					 hb_tag_t      table_tag,
-					 unsigned int  script_index,
-					 unsigned int  language_index);
-
-unsigned int
-hb_ot_layout_language_get_feature_index (hb_face_t    *face,
-					 hb_tag_t      table_tag,
-					 unsigned int  script_index,
-					 unsigned int  language_index,
-					 unsigned int  num_feature);
+hb_bool_t
+hb_ot_layout_language_get_feature_indexes (hb_face_t    *face,
+					   hb_tag_t      table_tag,
+					   unsigned int  script_index,
+					   unsigned int  language_index,
+					   unsigned int *feature_count /* IN/OUT */,
+					   unsigned int *feature_indexes /* OUT */);
 
-hb_tag_t
-hb_ot_layout_language_get_feature_tag (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  script_index,
-				       unsigned int  language_index,
-				       unsigned int  num_feature);
+hb_bool_t
+hb_ot_layout_language_get_feature_tags (hb_face_t    *face,
+					hb_tag_t      table_tag,
+					unsigned int  script_index,
+					unsigned int  language_index,
+					unsigned int *feature_count /* IN/OUT */,
+					hb_tag_t     *feature_tags /* OUT */);
 
 hb_bool_t
 hb_ot_layout_language_find_feature (hb_face_t    *face,
@@ -183,16 +169,13 @@ hb_ot_layout_language_find_feature (hb_face_t    *face,
 				    hb_tag_t      feature_tag,
 				    unsigned int *feature_index);
 
-unsigned int
-hb_ot_layout_feature_get_lookup_count (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  feature_index);
+hb_bool_t
+hb_ot_layout_feature_get_lookup_indexes (hb_face_t    *face,
+					 hb_tag_t      table_tag,
+					 unsigned int  feature_index,
+					 unsigned int *lookup_count /* IN/OUT */,
+					 unsigned int *lookup_indexes /* OUT */);
 
-unsigned int
-hb_ot_layout_feature_get_lookup_index (hb_face_t    *face,
-				       hb_tag_t      table_tag,
-				       unsigned int  feature_index,
-				       unsigned int  num_lookup);
 
 /*
  * GSUB
@@ -201,7 +184,7 @@ hb_ot_layout_feature_get_lookup_index (hb_face_t    *face,
 hb_bool_t
 hb_ot_layout_has_substitution (hb_face_t *face);
 
-/* GSUB is not font-size dependent, so we apply on face */
+/* XXX ?? GSUB is not font-size dependent, so we apply on face */
 hb_bool_t
 hb_ot_layout_substitute_lookup (hb_face_t                   *face,
 				hb_buffer_t                 *buffer,
diff --git a/pango/pango-ot-info.c b/pango/pango-ot-info.c
index 2fc4305..667aa8c 100644
--- a/pango/pango-ot-info.c
+++ b/pango/pango-ot-info.c
@@ -423,16 +423,12 @@ pango_ot_info_list_scripts (PangoOTInfo      *info,
 {
   hb_tag_t tt = get_hb_table_type (table_type);
   PangoOTTag *result;
-  unsigned int count, i;
-
-  count = hb_ot_layout_table_get_script_count (info->hb_face, tt);
+  unsigned int count;
 
+  hb_ot_layout_table_get_script_tags (info->hb_face, tt, &count, NULL);
   result = g_new (PangoOTTag, count + 1);
-
-  for (i = 0; i < count; i++)
-    result[i] = hb_ot_layout_table_get_script_tag (info->hb_face, tt, i);
-
-  result[i] = 0;
+  hb_ot_layout_table_get_script_tags (info->hb_face, tt, &count, result);
+  result[count] = 0;
 
   return result;
 }
@@ -457,19 +453,12 @@ pango_ot_info_list_languages (PangoOTInfo      *info,
 {
   hb_tag_t tt = get_hb_table_type (table_type);
   PangoOTTag *result;
-  unsigned int count, i;
-
-  count = hb_ot_layout_script_get_language_count (info->hb_face, tt,
-						  script_index);
+  unsigned int count;
 
+  hb_ot_layout_script_get_language_tags (info->hb_face, tt, script_index, &count, NULL);
   result = g_new (PangoOTTag, count + 1);
-
-  for (i = 0; i < count; i++)
-    result[i] = hb_ot_layout_script_get_language_tag (info->hb_face, tt,
-						      script_index,
-						      i);
-
-  result[i] = 0;
+  hb_ot_layout_script_get_language_tags (info->hb_face, tt, script_index, &count, result);
+  result[count] = 0;
 
   return result;
 }
@@ -498,21 +487,12 @@ pango_ot_info_list_features  (PangoOTInfo      *info,
 {
   hb_tag_t tt = get_hb_table_type (table_type);
   PangoOTTag *result;
-  unsigned int count, i;
-
-  count = hb_ot_layout_language_get_feature_count (info->hb_face, tt,
-						   script_index,
-						   language_index);
+  unsigned int count;
 
+  hb_ot_layout_language_get_feature_tags (info->hb_face, tt, script_index, language_index, &count, NULL);
   result = g_new (PangoOTTag, count + 1);
-
-  for (i = 0; i < count; i++)
-    result[i] = hb_ot_layout_language_get_feature_tag (info->hb_face, tt,
-						       script_index,
-						       language_index,
-						       i);
-
-  result[i] = 0;
+  hb_ot_layout_language_get_feature_tags (info->hb_face, tt, script_index, language_index, &count, result);
+  result[count] = 0;
 
   return result;
 }
@@ -529,28 +509,24 @@ _pango_ot_info_substitute  (const PangoOTInfo    *info,
       PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);
       hb_ot_layout_feature_mask_t mask;
       unsigned int lookup_count, j;
+      unsigned int lookup_indexes[100];
 
       if (rule->table_type != PANGO_OT_TABLE_GSUB)
 	continue;
 
       mask = rule->property_bit;
-      lookup_count = hb_ot_layout_feature_get_lookup_count (info->hb_face,
-							    HB_OT_TAG_GSUB,
-							    rule->feature_index);
+      lookup_count = G_N_ELEMENTS (lookup_indexes);
+      hb_ot_layout_feature_get_lookup_indexes (info->hb_face,
+					       HB_OT_TAG_GSUB,
+					       rule->feature_index,
+					       &lookup_count,
+					       lookup_indexes);
 
       for (j = 0; j < lookup_count; j++)
-        {
-	  unsigned int lookup_index;
-
-	  lookup_index = hb_ot_layout_feature_get_lookup_index (info->hb_face,
-								HB_OT_TAG_GSUB,
-								rule->feature_index,
-								j);
-	  hb_ot_layout_substitute_lookup (info->hb_face,
-					  buffer->buffer,
-					  lookup_index,
-					  rule->property_bit);
-	}
+	hb_ot_layout_substitute_lookup (info->hb_face,
+					buffer->buffer,
+					lookup_indexes[j],
+					rule->property_bit);
     }
 }
 
@@ -580,28 +556,24 @@ _pango_ot_info_position    (const PangoOTInfo    *info,
       PangoOTRule *rule = &g_array_index (ruleset->rules, PangoOTRule, i);
       hb_ot_layout_feature_mask_t mask;
       unsigned int lookup_count, j;
+      unsigned int lookup_indexes[100];
 
       if (rule->table_type != PANGO_OT_TABLE_GPOS)
 	continue;
 
       mask = rule->property_bit;
-      lookup_count = hb_ot_layout_feature_get_lookup_count (info->hb_face,
-							    HB_OT_TAG_GPOS,
-							    rule->feature_index);
+      lookup_count = G_N_ELEMENTS (lookup_indexes);
+      hb_ot_layout_feature_get_lookup_indexes (info->hb_face,
+					       HB_OT_TAG_GPOS,
+					       rule->feature_index,
+					       &lookup_count,
+					       lookup_indexes);
 
       for (j = 0; j < lookup_count; j++)
-        {
-	  unsigned int lookup_index;
-
-	  lookup_index = hb_ot_layout_feature_get_lookup_index (info->hb_face,
-								HB_OT_TAG_GPOS,
-								rule->feature_index,
-								j);
-	  hb_ot_layout_position_lookup (info->hb_face, hb_font,
-					buffer->buffer,
-					lookup_index,
-					rule->property_bit);
-	}
+	hb_ot_layout_position_lookup (info->hb_face, hb_font,
+				      buffer->buffer,
+				      lookup_indexes[j],
+				      rule->property_bit);
 
       buffer->applied_gpos = TRUE;
     }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]