提交 e21899bc 编写于 作者: B Behdad Esfahbod

Fix array query API

The array query APIs now all do:

  - Return the total number of items
  - Take a start_offset, such that individual items can be fetched
  - The _count IN/OUT variable always has number of items written
    into the array upon return of the function
上级 3b59306b
......@@ -5,7 +5,6 @@
- Future-proof metrics struct
hb-ot:
- Fix ot query APIs
- Rename hb_internal_glyph_info_t to hb_ot_glyph_info_t
- Add query API for aalt-like features
- HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH vs LookupType::... mess
......@@ -69,16 +69,19 @@ struct RecordArrayOf : ArrayOf<Record<Type> > {
if (HB_UNLIKELY (i >= this->len)) return Null(Tag);
return (*this)[i].tag;
}
inline bool get_tags (unsigned int *record_count /* IN/OUT */,
hb_tag_t *record_tags /* OUT */) const
inline unsigned int get_tags (unsigned int start_offset,
unsigned int *record_count /* IN/OUT */,
hb_tag_t *record_tags /* OUT */) const
{
const Record<Type> *a = this->const_array();
unsigned int count = MIN (this->len, *record_count);
for (unsigned int i = 0; i < count; i++)
record_tags[i] = a[i].tag;
if (record_count) {
unsigned int count = MIN (MIN (0, (unsigned int) this->len - start_offset), *record_count);
const Record<Type> *array = this->const_array() + start_offset;
for (unsigned int i = 0; i < count; i++)
record_tags[i] = array[i].tag;
*record_count = this->len;
return !!this->len;
*record_count = this->len;
}
return this->len;
}
inline bool find_index (hb_tag_t tag, unsigned int *index) const
{
......@@ -120,16 +123,19 @@ struct IndexArray : ArrayOf<USHORT>
return NO_INDEX;
return this->const_array()[i];
}
inline bool get_indexes (unsigned int *_count /* IN/OUT */,
unsigned int *_indexes /* OUT */) const
inline unsigned int get_indexes (unsigned int start_offset,
unsigned int *_count /* IN/OUT */,
unsigned int *_indexes /* OUT */) const
{
unsigned int count = MIN (this->len, *_count);
const USHORT *a = this->const_array();
for (unsigned int i = 0; i < count; i++)
_indexes[i] = a[i];
if (_count) {
unsigned int count = MIN (MIN (0, (unsigned int) this->len - start_offset), *_count);
const USHORT *array = this->const_array() + start_offset;
for (unsigned int i = 0; i < count; i++)
_indexes[i] = array[i];
*_count = this->len;
return !!this->len;
*_count = this->len;
}
return this->len;
}
};
......@@ -145,9 +151,10 @@ struct LangSys
{ return featureIndex.len; }
inline hb_tag_t get_feature_index (unsigned int i) const
{ return featureIndex[i]; }
inline bool get_feature_indexes (unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */) const
{ return featureIndex.get_indexes (feature_count, feature_indexes); }
inline unsigned int get_feature_indexes (unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */) const
{ return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); }
inline bool has_required_feature (void) const { return reqFeatureIndex != 0xffff; }
inline int get_required_feature_index (void) const
......@@ -178,9 +185,10 @@ struct Script
{ return langSys.len; }
inline const Tag& get_lang_sys_tag (unsigned int i) const
{ return langSys.get_tag (i); }
inline bool get_lang_sys_tags (unsigned int *lang_sys_count /* IN/OUT */,
hb_tag_t *lang_sys_tags /* OUT */) const
{ return langSys.get_tags (lang_sys_count, lang_sys_tags); }
inline unsigned int get_lang_sys_tags (unsigned int start_offset,
unsigned int *lang_sys_count /* IN/OUT */,
hb_tag_t *lang_sys_tags /* OUT */) const
{ return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); }
inline const LangSys& get_lang_sys (unsigned int i) const
{
if (i == NO_INDEX) return get_default_lang_sys ();
......@@ -217,9 +225,10 @@ struct Feature
{ return lookupIndex.len; }
inline hb_tag_t get_lookup_index (unsigned int i) const
{ return lookupIndex[i]; }
inline bool get_lookup_indexes (unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_tags /* OUT */) const
{ return lookupIndex.get_indexes (lookup_count, lookup_tags); }
inline unsigned int get_lookup_indexes (unsigned int start_index,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_tags /* OUT */) const
{ return lookupIndex.get_indexes (start_index, lookup_count, lookup_tags); }
inline bool sanitize (SANITIZE_ARG_DEF) {
TRACE_SANITIZE ();
......
......@@ -42,25 +42,31 @@ ASSERT_SIZE (AttachPoint, 2);
struct AttachList
{
inline bool get_attach_points (hb_codepoint_t glyph_id,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{
unsigned int index = (this+coverage) (glyph_id);
if (index == NOT_COVERED)
{
*point_count = 0;
return false;
if (point_count)
*point_count = 0;
return 0;
}
const AttachPoint &points = this+attachPoint[index];
unsigned int count = MIN (points.len, *point_count);
for (unsigned int i = 0; i < count; i++)
point_array[i] = points[i];
if (point_count) {
const USHORT *array = points.const_array () + start_offset;
unsigned int count = MIN (MIN (0, (unsigned int) points.len - start_offset), *point_count);
for (unsigned int i = 0; i < count; i++)
point_array[i] = array[i];
*point_count = points.len;
*point_count = points.len;
}
return true;
return points.len;
}
inline bool sanitize (SANITIZE_ARG_DEF) {
......@@ -185,17 +191,22 @@ struct CaretValue
struct LigGlyph
{
inline void get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
inline unsigned int get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
{
if (caret_count) {
const OffsetTo<CaretValue> *array = carets.const_array () + start_offset;
unsigned int count = MIN (MIN (0, (unsigned int) carets.len - start_offset), *caret_count);
for (unsigned int i = 0; i < count; i++)
caret_array[i] = (this+array[i]).get_caret_value (context, glyph_id);
unsigned int count = MIN (carets.len, *caret_count);
for (unsigned int i = 0; i < count; i++)
caret_array[i] = (this+carets[i]).get_caret_value (context, glyph_id);
*caret_count = carets.len;
}
*caret_count = carets.len;
return carets.len;
}
inline bool sanitize (SANITIZE_ARG_DEF) {
......@@ -213,20 +224,21 @@ ASSERT_SIZE (LigGlyph, 2);
struct LigCaretList
{
inline bool get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
inline unsigned int get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
{
unsigned int index = (this+coverage) (glyph_id);
if (index == NOT_COVERED)
{
*caret_count = 0;
return false;
if (caret_count)
*caret_count = 0;
return 0;
}
const LigGlyph &lig_glyph = this+ligGlyph[index];
lig_glyph.get_lig_carets (context, glyph_id, caret_count, caret_array);
return true;
return lig_glyph.get_lig_carets (context, glyph_id, start_offset, caret_count, caret_array);
}
inline bool sanitize (SANITIZE_ARG_DEF) {
......@@ -317,17 +329,19 @@ struct GDEF
{ return (this+markAttachClassDef).get_class (glyph); }
inline bool has_attach_points () const { return attachList != 0; }
inline bool get_attach_points (hb_codepoint_t glyph_id,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{ return (this+attachList).get_attach_points (glyph_id, point_count, point_array); }
inline unsigned int get_attach_points (hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */) const
{ return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); }
inline bool has_lig_carets () const { return ligCaretList != 0; }
inline bool get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
{ return (this+ligCaretList).get_lig_carets (context, glyph_id, caret_count, caret_array); }
inline unsigned int get_lig_carets (hb_ot_layout_context_t *context,
hb_codepoint_t glyph_id,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */) const
{ return (this+ligCaretList).get_lig_carets (context, glyph_id, start_offset, caret_count, caret_array); }
inline bool has_mark_sets () const { return version >= 0x00010002 && markGlyphSetsDef[0] != 0; }
inline bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
......
......@@ -907,9 +907,10 @@ struct GSUBGPOS
{ return (this+scriptList).len; }
inline const Tag& get_script_tag (unsigned int i) const
{ return (this+scriptList).get_tag (i); }
inline bool get_script_tags (unsigned int *script_count /* IN/OUT */,
hb_tag_t *script_tags /* OUT */) const
{ return (this+scriptList).get_tags (script_count, script_tags); }
inline unsigned int get_script_tags (unsigned int start_offset,
unsigned int *script_count /* IN/OUT */,
hb_tag_t *script_tags /* OUT */) const
{ return (this+scriptList).get_tags (start_offset, script_count, script_tags); }
inline const Script& get_script (unsigned int i) const
{ return (this+scriptList)[i]; }
inline bool find_script_index (hb_tag_t tag, unsigned int *index) const
......@@ -919,9 +920,10 @@ struct GSUBGPOS
{ return (this+featureList).len; }
inline const Tag& get_feature_tag (unsigned int i) const
{ return (this+featureList).get_tag (i); }
inline bool get_feature_tags (unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */) const
{ return (this+featureList).get_tags (feature_count, feature_tags); }
inline unsigned int get_feature_tags (unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */) const
{ return (this+featureList).get_tags (start_offset, feature_count, feature_tags); }
inline const Feature& get_feature (unsigned int i) const
{ return (this+featureList)[i]; }
inline bool find_feature_index (hb_tag_t tag, unsigned int *index) const
......
......@@ -301,26 +301,28 @@ hb_ot_layout_build_glyph_classes (hb_face_t *face,
_hb_ot_layout_set_glyph_class (face, glyphs[i], (hb_ot_layout_glyph_class_t) klasses[i]);
}
hb_bool_t
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */)
{
return _get_gdef (face).get_attach_points (glyph, point_count, point_array);
return _get_gdef (face).get_attach_points (glyph, start_offset, point_count, point_array);
}
hb_bool_t
unsigned int
hb_ot_layout_get_lig_carets (hb_face_t *face,
hb_font_t *font,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */)
{
hb_ot_layout_context_t context;
context.font = font;
context.face = face;
return _get_gdef (face).get_lig_carets (&context, glyph, caret_count, caret_array);
return _get_gdef (face).get_lig_carets (&context, glyph, start_offset, caret_count, caret_array);
}
/*
......@@ -339,15 +341,16 @@ get_gsubgpos_table (hb_face_t *face,
}
hb_bool_t
unsigned int
hb_ot_layout_table_get_script_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *script_count /* IN/OUT */,
hb_tag_t *script_tags /* OUT */)
{
const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
return g.get_script_tags (script_count, script_tags);
return g.get_script_tags (start_offset, script_count, script_tags);
}
hb_bool_t
......@@ -374,28 +377,30 @@ hb_ot_layout_table_find_script (hb_face_t *face,
return FALSE;
}
hb_bool_t
unsigned int
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */)
{
const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
return g.get_feature_tags (feature_count, feature_tags);
return g.get_feature_tags (start_offset, feature_count, feature_tags);
}
hb_bool_t
unsigned int
hb_ot_layout_script_get_language_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int start_offset,
unsigned int *language_count /* IN/OUT */,
hb_tag_t *language_tags /* OUT */)
{
const Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
return s.get_lang_sys_tags (language_count, language_tags);
return s.get_lang_sys_tags (start_offset, language_count, language_tags);
}
hb_bool_t
......@@ -433,25 +438,27 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
return l.has_required_feature ();
}
hb_bool_t
unsigned int
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */)
{
const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
return l.get_feature_indexes (feature_count, feature_indexes);
return l.get_feature_indexes (start_offset, feature_count, feature_indexes);
}
hb_bool_t
unsigned int
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */)
{
......@@ -459,7 +466,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face,
const LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
ASSERT_STATIC (sizeof (unsigned int) == sizeof (hb_tag_t));
hb_bool_t ret = l.get_feature_indexes (feature_count, (unsigned int *) feature_tags);
unsigned int ret = l.get_feature_indexes (start_offset, feature_count, (unsigned int *) feature_tags);
if (feature_tags) {
unsigned int count = *feature_count;
......@@ -497,17 +504,18 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
return FALSE;
}
hb_bool_t
unsigned int
hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
hb_tag_t table_tag,
unsigned int feature_index,
unsigned int start_offset,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */)
{
const GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
const Feature &f = g.get_feature (feature_index);
return f.get_lookup_indexes (lookup_count, lookup_indexes);
return f.get_lookup_indexes (start_offset, lookup_count, lookup_indexes);
}
......
......@@ -73,17 +73,19 @@ hb_ot_layout_build_glyph_classes (hb_face_t *face,
/* Not that useful. Provides list of attach points for a glyph that a
* client may want to cache */
hb_bool_t
unsigned int
hb_ot_layout_get_attach_points (hb_face_t *face,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */);
/* Ligature caret positions */
hb_bool_t
unsigned int
hb_ot_layout_get_lig_carets (hb_face_t *face,
hb_font_t *font,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *caret_count /* IN/OUT */,
int *caret_array /* OUT */);
......@@ -98,9 +100,10 @@ hb_ot_layout_get_lig_carets (hb_face_t *face,
#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')
hb_bool_t
unsigned int
hb_ot_layout_table_get_script_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *script_count /* IN/OUT */,
hb_tag_t *script_tags /* OUT */);
......@@ -110,16 +113,18 @@ hb_ot_layout_table_find_script (hb_face_t *face,
hb_tag_t script_tag,
unsigned int *script_index);
hb_bool_t
unsigned int
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */);
hb_bool_t
unsigned int
hb_ot_layout_script_get_language_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int start_offset,
unsigned int *language_count /* IN/OUT */,
hb_tag_t *language_tags /* OUT */);
......@@ -137,19 +142,21 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
unsigned int language_index,
unsigned int *feature_index);
hb_bool_t
unsigned int
hb_ot_layout_language_get_feature_indexes (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
unsigned int *feature_indexes /* OUT */);
hb_bool_t
unsigned int
hb_ot_layout_language_get_feature_tags (hb_face_t *face,
hb_tag_t table_tag,
unsigned int script_index,
unsigned int language_index,
unsigned int start_offset,
unsigned int *feature_count /* IN/OUT */,
hb_tag_t *feature_tags /* OUT */);
......@@ -161,10 +168,11 @@ hb_ot_layout_language_find_feature (hb_face_t *face,
hb_tag_t feature_tag,
unsigned int *feature_index);
hb_bool_t
unsigned int
hb_ot_layout_feature_get_lookup_indexes (hb_face_t *face,
hb_tag_t table_tag,
unsigned int feature_index,
unsigned int start_offset,
unsigned int *lookup_count /* IN/OUT */,
unsigned int *lookup_indexes /* OUT */);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册