[feat] Add feature iteration API

This commit is contained in:
Ebrahim Byagowi 2018-11-01 22:24:42 +03:30 committed by Behdad Esfahbod
parent 7a0471aa35
commit fbad794bd2
4 changed files with 96 additions and 40 deletions

View File

@ -123,6 +123,11 @@ struct FeatureName
(base+settingTable).sanitize (c, nSettings)));
}
inline hb_aat_layout_feature_type_t get_feature () const
{ return (hb_aat_layout_feature_type_t) (unsigned int) feature; }
inline unsigned int get_name_id () const { return nameIndex; }
protected:
HBUINT16 feature; /* Feature type. */
HBUINT16 nSettings; /* The number of records in the setting name array. */
@ -143,14 +148,21 @@ struct feat
{
static const hb_tag_t tableTag = HB_AAT_TAG_feat;
inline const FeatureName& get_feature (hb_aat_layout_feature_type_t key) const
inline unsigned int get_features (unsigned int start_offset,
unsigned int *record_count,
hb_aat_layout_feature_record_t *record_buffer) const
{
const FeatureName* feature = (FeatureName*) hb_bsearch (&key, &names,
FeatureName::static_size,
sizeof (FeatureName),
FeatureName::cmp);
return feature ? *feature : Null (FeatureName);
unsigned int feature_count = featureNameCount;
if (record_count)
{
unsigned int len = MIN (feature_count - start_offset, *record_count);
for (unsigned int i = 0; i < len; i++)
{
record_buffer[i].feature = names[i + start_offset].get_feature ();
record_buffer[i].name_id = names[i + start_offset].get_name_id ();
}
}
return featureNameCount;
}
inline unsigned int get_settings (hb_aat_layout_feature_type_t type,
@ -159,8 +171,14 @@ struct feat
unsigned int *selectors_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */) const
{
return get_feature (type).get_settings (this, default_setting,
start_offset, selectors_count, selectors_buffer);
const FeatureName* feature = (FeatureName*) hb_bsearch (&type, &names,
FeatureName::static_size,
sizeof (FeatureName),
FeatureName::cmp);
return (feature ? *feature : Null (FeatureName)).get_settings (this, default_setting,
start_offset, selectors_count,
selectors_buffer);
}
inline bool sanitize (hb_sanitize_context_t *c) const

View File

@ -169,12 +169,6 @@ AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_,
ankr_table = ankr_table_;
ankr_end = ankr_end_;
}
static inline const AAT::feat&
_get_feat (hb_face_t *face)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::feat);
return *(hb_ot_face_data (face)->feat.get ());
}
/*
@ -309,9 +303,7 @@ _hb_aat_language_get (hb_face_t *face,
/**
* hb_aat_layout_get_feature_settings:
* @face: a font face.
* @type: AAT feature id you are querying, for example 1 for
* "Ligatures" feature, 37 for the "Lower Case" feature,
* 38 for the "Upper Case" feature, etc.
* @feature: AAT feature id you are querying.
* @default_setting: (out): default value for the type. If it is HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED
* means none is selected as default and the feature is not exclusive.
* @start_offset: start offset, if you are iterating
@ -324,12 +316,22 @@ _hb_aat_language_get (hb_face_t *face,
*/
unsigned int
hb_aat_layout_get_feature_settings (hb_face_t *face,
hb_aat_layout_feature_type_t type,
hb_aat_layout_feature_type_t feature,
hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */
unsigned int start_offset,
unsigned int *selectors_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_type_selector_t *selectors_buffer /* OUT. May be NULL. */)
{
return _get_feat (face).get_settings (type, default_setting,
start_offset, selectors_count, selectors_buffer);
return face->table.feat->get_settings (feature, default_setting,
start_offset, selectors_count, selectors_buffer);
}
unsigned int
hb_aat_layout_get_features (hb_face_t *face,
unsigned int start_offset,
unsigned int *record_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */)
{
return face->table.feat->get_features (start_offset, record_count, record_buffer);
}

View File

@ -60,6 +60,25 @@ typedef enum
HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED = 0xFFFF
} hb_aat_layout_feature_type_t;
/**
* hb_aat_layout_feature_record_t:
*
* Feature record and
*
* Since: REPLACEME
**/
typedef struct hb_aat_layout_feature_record_t
{
hb_aat_layout_feature_type_t feature;
hb_ot_name_id_t name_id;
} hb_aat_layout_feature_record_t;
HB_EXTERN unsigned int
hb_aat_layout_get_features (hb_face_t *face,
unsigned int start_offset,
unsigned int *record_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_record_t *record_buffer /* OUT. May be NULL. */);
/**
* hb_aat_feature_t:
*
@ -72,7 +91,7 @@ typedef unsigned int hb_aat_layout_feature_setting_t;
/**
* hb_aat_layout_feature_type_selector_t:
*
* Feature type record
* Feature type selector
*
* Since: REPLACEME
**/
@ -84,7 +103,7 @@ typedef struct hb_aat_layout_feature_type_selector_t
HB_EXTERN unsigned int
hb_aat_layout_get_feature_settings (hb_face_t *face,
hb_aat_layout_feature_type_t type,
hb_aat_layout_feature_type_t feature,
hb_aat_layout_feature_setting_t *default_setting, /* OUT. May be NULL. */
unsigned int start_offset,
unsigned int *selectors_count, /* IN/OUT. May be NULL. */

View File

@ -30,6 +30,23 @@
/* Unit tests for hb-aat.h */
static hb_face_t *face;
static hb_face_t *sbix;
static void
test_aat_get_features (void)
{
hb_aat_layout_feature_record_t records[3];
unsigned int record_count = 3;
g_assert_cmpuint (11, ==, hb_aat_layout_get_features (face, 0, &record_count, records));
g_assert_cmpuint (1, ==, records[0].feature);
g_assert_cmpuint (258, ==, records[0].name_id);
g_assert_cmpuint (3, ==, records[1].feature);
g_assert_cmpuint (261, ==, records[1].name_id);
g_assert_cmpuint (6, ==, records[2].feature);
g_assert_cmpuint (265, ==, records[2].name_id);
}
static void
test_aat_get_feature_settings (void)
{
@ -37,10 +54,8 @@ test_aat_get_feature_settings (void)
hb_aat_layout_feature_type_selector_t records[3];
unsigned int count = 3;
hb_face_t *face = hb_test_open_font_file ("fonts/aat-feat.ttf");
g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting,
0, &count, records));
g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18,
&default_setting, 0, &count, records));
g_assert_cmpuint (3, ==, count);
g_assert_cmpuint (0, ==, default_setting);
@ -54,8 +69,8 @@ test_aat_get_feature_settings (void)
g_assert_cmpuint (296, ==, records[2].name_id);
count = 3;
g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, 18, &default_setting,
3, &count, records));
g_assert_cmpuint (4, ==, hb_aat_layout_get_feature_settings (face, (hb_aat_layout_feature_type_t) 18,
&default_setting, 3, &count, records));
g_assert_cmpuint (1, ==, count);
g_assert_cmpuint (0, ==, default_setting);
@ -64,8 +79,8 @@ test_aat_get_feature_settings (void)
count = 1;
g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, 14, &default_setting,
0, &count, records));
g_assert_cmpuint (1, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_TYPOGRAPHIC_EXTRAS,
&default_setting, 0, &count, records));
g_assert_cmpuint (1, ==, count);
g_assert_cmpuint (HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, ==, default_setting);
@ -74,16 +89,12 @@ test_aat_get_feature_settings (void)
count = 100;
g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, 32, NULL,
0, &count, records));
g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (face, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED,
NULL, 0, &count, records));
g_assert_cmpuint (0, ==, count);
hb_face_destroy (face);
hb_face_t *sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf");
g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, 100, NULL,
0, &count, records));
hb_face_destroy (sbix);
g_assert_cmpuint (0, ==, hb_aat_layout_get_feature_settings (sbix, HB_AAT_LAYOUT_FEATURE_TYPE_UNDEFINED, NULL,
0, &count, records));
}
int
@ -91,7 +102,13 @@ main (int argc, char **argv)
{
hb_test_init (&argc, &argv);
hb_test_add (test_aat_get_features);
hb_test_add (test_aat_get_feature_settings);
return hb_test_run();
face = hb_test_open_font_file ("fonts/aat-feat.ttf");
sbix = hb_test_open_font_file ("fonts/chromacheck-sbix.ttf");
unsigned int status = hb_test_run ();
hb_face_destroy (sbix);
hb_face_destroy (face);
return status;
}