Add script and language public getter API
This commit is contained in:
parent
40a81314fa
commit
706ab25a4c
|
@ -34,6 +34,8 @@
|
||||||
#include "hb-ot-layout-private.h"
|
#include "hb-ot-layout-private.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define NO_INDEX ((unsigned int) 0xFFFF)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Int types
|
* Int types
|
||||||
*/
|
*/
|
||||||
|
@ -153,7 +155,7 @@
|
||||||
|
|
||||||
#define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \
|
#define DEFINE_TAG_ARRAY_INTERFACE(Type, name) \
|
||||||
DEFINE_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; \
|
return (*this)[i].tag; \
|
||||||
}
|
}
|
||||||
#define DEFINE_TAG_LIST_INTERFACE(Type, name) \
|
#define DEFINE_TAG_LIST_INTERFACE(Type, name) \
|
||||||
|
@ -163,16 +165,21 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DEFINE_TAG_FIND_INTERFACE(Type, name) \
|
#define DEFINE_TAG_FIND_INTERFACE(Type, name) \
|
||||||
inline const Type* find_##name (hb_tag_t tag) const { \
|
inline bool find_##name##_index (hb_tag_t tag, unsigned int *name##_index) const { \
|
||||||
for (unsigned int i = 0; i < get_##name##_count (); i++) \
|
const Tag t = tag; \
|
||||||
if (tag == get_##name##_tag (i)) \
|
for (unsigned int i = 0; i < get_##name##_count (); i++) { \
|
||||||
return &get_##name (i); \
|
if (t == get_##name##_tag (i)) { \
|
||||||
return NULL; \
|
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 { \
|
inline const Type& get_##name##_by_tag (hb_tag_t tag) const { \
|
||||||
const Type* res = find_##name (tag); \
|
unsigned int i; \
|
||||||
if (res) \
|
if (find_##name##_index (tag, &i)) \
|
||||||
return *res; \
|
return get_##name (i); \
|
||||||
else \
|
else \
|
||||||
return Null##Type; \
|
return Null##Type; \
|
||||||
}
|
}
|
||||||
|
@ -390,7 +397,7 @@ typedef struct OffsetTable {
|
||||||
friend struct TTCHeader;
|
friend struct TTCHeader;
|
||||||
|
|
||||||
DEFINE_TAG_ARRAY_INTERFACE (OpenTypeTable, table); /* get_table_count(), get_table(i), get_table_tag(i) */
|
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:
|
private:
|
||||||
/* OpenTypeTables, in no particular order */
|
/* OpenTypeTables, in no particular order */
|
||||||
|
@ -509,10 +516,13 @@ struct LangSys {
|
||||||
|
|
||||||
DEFINE_INDEX_ARRAY_INTERFACE (feature);
|
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 {
|
inline int get_required_feature_index (void) const {
|
||||||
if (reqFeatureIndex == 0xffff)
|
if (reqFeatureIndex == 0xffff)
|
||||||
return -1;
|
return NO_INDEX;
|
||||||
return reqFeatureIndex;;
|
return reqFeatureIndex;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -543,7 +553,7 @@ struct Script {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO bsearch */
|
/* 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 {
|
inline const bool has_default_lang_sys (void) const {
|
||||||
return defaultLangSys != 0;
|
return defaultLangSys != 0;
|
||||||
|
@ -940,8 +950,8 @@ typedef struct GSUBGPOS {
|
||||||
DEFINE_LIST_INTERFACE (Lookup, lookup ); /* get_lookup_count (), get_lookup (i) */
|
DEFINE_LIST_INTERFACE (Lookup, lookup ); /* get_lookup_count (), get_lookup (i) */
|
||||||
|
|
||||||
/* TODO bsearch */
|
/* TODO bsearch */
|
||||||
DEFINE_TAG_FIND_INTERFACE (Script, script ); /* find_script (), get_script_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(), get_feature_by_tag(tag) */
|
DEFINE_TAG_FIND_INTERFACE (Feature, feature); /* find_feature_index(), get_feature_by_tag(tag) */
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DEFINE_LIST_ARRAY(Script, script);
|
DEFINE_LIST_ARRAY(Script, script);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
struct _hb_ot_layout_t {
|
struct _hb_ot_layout_t {
|
||||||
const GDEF *gdef;
|
const GDEF *gdef;
|
||||||
const GSUB *gsub;
|
const GSUB *gsub;
|
||||||
//const GPOS *gpos;
|
const /*XXX*/GSUBGPOS *gpos;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
unsigned char *klasses;
|
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->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->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;
|
return layout;
|
||||||
}
|
}
|
||||||
|
@ -243,3 +243,126 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
hb_ot_layout_set_glyph_class (layout, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[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;
|
||||||
|
}
|
||||||
|
|
|
@ -78,6 +78,62 @@ hb_ot_layout_build_glyph_classes (hb_ot_layout_t *layout,
|
||||||
unsigned char *klasses,
|
unsigned char *klasses,
|
||||||
uint16_t count);
|
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();
|
HB_END_DECLS();
|
||||||
|
|
||||||
#endif /* HB_OT_LAYOUT_H */
|
#endif /* HB_OT_LAYOUT_H */
|
||||||
|
|
|
@ -103,7 +103,7 @@ main (int argc, char **argv)
|
||||||
? " Default Language System\n"
|
? " Default Language System\n"
|
||||||
: " Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
|
: " Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
|
||||||
(const char *)script.get_lang_sys_tag (n_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");
|
printf (" No required feature\n");
|
||||||
|
|
||||||
int num_features = langsys.get_feature_count ();
|
int num_features = langsys.get_feature_count ();
|
||||||
|
|
Loading…
Reference in New Issue