Finish script, language, and feature public API

This commit is contained in:
Behdad Esfahbod 2008-01-28 07:40:10 -05:00
parent 706ab25a4c
commit 4a26ea408c
3 changed files with 138 additions and 37 deletions

View File

@ -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) */

View File

@ -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;
}

View File

@ -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);
/*