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
diff --git a/TODO b/TODO
index 5df48a3..a12d0ca 100644
--- a/TODO
+++ b/TODO
@@ -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
diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh
index 3d1bc34..704ab19 100644
--- a/src/hb-ot-layout-common-private.hh
+++ b/src/hb-ot-layout-common-private.hh
@@ -69,16 +69,19 @@
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 @@
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 @@
{ 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 @@
{ 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 @@
{ 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 ();
diff --git a/src/hb-ot-layout-gdef-private.hh b/src/hb-ot-layout-gdef-private.hh
index 69f90fe..d96bb16 100644
--- a/src/hb-ot-layout-gdef-private.hh
+++ b/src/hb-ot-layout-gdef-private.hh
@@ -42,25 +42,31 @@
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 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 @@
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 @@
{ 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
diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh
index 91703da..4a5b8b2 100644
--- a/src/hb-ot-layout-gsubgpos-private.hh
+++ b/src/hb-ot-layout-gsubgpos-private.hh
@@ -907,9 +907,10 @@
{ 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 @@
{ 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
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 67b2b9a..89c7374 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -301,26 +301,28 @@
_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 @@
}
-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 @@
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 @@
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 @@
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 @@
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);
}
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 54f785f..312482a 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -73,17 +73,19 @@
/* 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 @@
#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_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 @@
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_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 */);