From 4a26ea408c87f0bb59deca9ff44008d138471aa3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 28 Jan 2008 07:40:10 -0500 Subject: [PATCH] Finish script, language, and feature public API --- src/hb-ot-layout-open-private.h | 22 ++++-- src/hb-ot-layout.cc | 119 ++++++++++++++++++++++++-------- src/hb-ot-layout.h | 34 ++++++++- 3 files changed, 138 insertions(+), 37 deletions(-) diff --git a/src/hb-ot-layout-open-private.h b/src/hb-ot-layout-open-private.h index 3127c4dd2..ce629db02 100644 --- a/src/hb-ot-layout-open-private.h +++ b/src/hb-ot-layout-open-private.h @@ -112,7 +112,6 @@ 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) \ @@ -124,10 +123,11 @@ } #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 (); \ } @@ -194,7 +194,7 @@ 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) */ diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 33bfe4209..22fa81c5a 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -52,11 +52,28 @@ 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; - 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 - + if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; + return FALSE; +} + +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 (feature_index) *feature_index = l.get_required_feature_index (); + + return l.has_required_feature (); +} + +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; } diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index abea248dd..895cc44a8 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -37,6 +37,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); /*