From 706ab25a4cb043d46e6088aa0a7184ee200276c9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 05:58:50 -0500 Subject: [PATCH] Add script and language public getter API --- src/hb-ot-layout-open-private.h | 40 ++++++---- src/hb-ot-layout.cc | 127 +++++++++++++++++++++++++++++++- src/hb-ot-layout.h | 56 ++++++++++++++ src/main.cc | 2 +- 4 files changed, 207 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 95adfa528..3127c4dd2 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -34,6 +34,8 @@ #include "hb-ot-layout-private.h" +#define NO_INDEX ((unsigned int) 0xFFFF) + /* * Int types */ @@ -153,7 +155,7 @@ #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) \ @@ -163,16 +165,21 @@ } #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); diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 4cd70def0..33bfe4209 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -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; +} diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index c515d5b9e..abea248dd 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -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 */ diff --git a/src/main.cc b/src/main.cc index 1a81ad180..b149e1118 100644 --- a/src/main.cc +++ b/src/main.cc @@ -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 ();