diff options
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh')
-rw-r--r-- | Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh | 193 |
1 files changed, 139 insertions, 54 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh index b1fcd68777f..f4d0238ea07 100644 --- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh +++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type.hh @@ -231,22 +231,31 @@ struct FixedVersion * Use: (base+offset) */ -template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0, ""); }; -template <typename Type> struct assert_has_min_size<Type, false> {}; +template <typename Type, bool has_null> +struct _hb_has_null +{ + static inline const Type *get_null (void) { return nullptr; } + static inline Type *get_crap (void) { return nullptr; } +}; +template <typename Type> +struct _hb_has_null<Type, true> +{ + static inline const Type *get_null (void) { return &Null(Type); } + static inline Type *get_crap (void) { return &Crap(Type); } +}; template <typename Type, typename OffsetType=HBUINT16, bool has_null=true> struct OffsetTo : Offset<OffsetType, has_null> { - static_assert (sizeof (assert_has_min_size<Type, has_null>) || true, ""); - inline const Type& operator () (const void *base) const { - if (unlikely (this->is_null ())) return Null (Type); + if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_null (); return StructAtOffset<const Type> (base, *this); } inline Type& operator () (void *base) const { if (unlikely (this->is_null ())) return Crap (Type); + if (unlikely (this->is_null ())) return *_hb_has_null<Type, has_null>::get_crap (); return StructAtOffset<Type> (base, *this); } @@ -322,6 +331,7 @@ struct OffsetTo : Offset<OffsetType, has_null> DEFINE_SIZE_STATIC (sizeof (OffsetType)); }; template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {}; + template <typename Base, typename OffsetType, bool has_null, typename Type> static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); } template <typename Base, typename OffsetType, bool has_null, typename Type> @@ -335,6 +345,8 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> template <typename Type> struct UnsizedArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); @@ -358,8 +370,20 @@ struct UnsizedArrayOf inline unsigned int get_size (unsigned int len) const { return len * Type::static_size; } - inline hb_array_t<Type> as_array (unsigned int len) { return hb_array_t<Type> (arrayZ, len); } - inline hb_array_t<const Type> as_array (unsigned int len) const { return hb_array_t<const Type> (arrayZ, len); } + inline hb_array_t<Type> as_array (unsigned int len) + { return hb_array (arrayZ, len); } + inline hb_array_t<const Type> as_array (unsigned int len) const + { return hb_array (arrayZ, len); } + + template <typename T> + inline Type &lsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).lsearch (x, ¬_found); } + template <typename T> + inline const Type &lsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).lsearch (x, ¬_found); } + + inline void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array (len).qsort (start, end); } inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { @@ -406,7 +430,7 @@ struct UnsizedArrayOf public: Type arrayZ[VAR]; public: - DEFINE_SIZE_ARRAY (0, arrayZ); + DEFINE_SIZE_UNBOUNDED (0); }; /* Unsized array of offset's */ @@ -419,9 +443,18 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> { inline const Type& operator [] (unsigned int i) const { - return this+this->arrayZ[i]; + const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + return this+*p; + } + inline Type& operator [] (unsigned int i) + { + const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; + if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + return this+*p; } + inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const { TRACE_SANITIZE (this); @@ -435,26 +468,39 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType, has_null> } }; +/* An array with sorted elements. Supports binary searching. */ +template <typename Type> +struct SortedUnsizedArrayOf : UnsizedArrayOf<Type> +{ + inline hb_sorted_array_t<Type> as_array (unsigned int len) + { return hb_sorted_array (this->arrayZ, len); } + inline hb_sorted_array_t<const Type> as_array (unsigned int len) const + { return hb_sorted_array (this->arrayZ, len); } + + template <typename T> + inline Type &bsearch (unsigned int len, const T &x, Type ¬_found = Crap (Type)) + { return *as_array (len).bsearch (x, ¬_found); } + template <typename T> + inline const Type &bsearch (unsigned int len, const T &x, const Type ¬_found = Null (Type)) const + { return *as_array (len).bsearch (x, ¬_found); } + template <typename T> + inline bool bfind (unsigned int len, const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array (len).bfind (x, i, not_found, to_store); } +}; + + /* An array with a number of elements. */ template <typename Type, typename LenType=HBUINT16> struct ArrayOf { + static_assert ((bool) (unsigned) hb_static_size (Type), ""); + enum { item_size = Type::static_size }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); - inline const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const - { - unsigned int count = len; - if (unlikely (start_offset > count)) - count = 0; - else - count -= start_offset; - count = MIN (count, *pcount); - *pcount = count; - return arrayZ + start_offset; - } - inline const Type& operator [] (unsigned int i) const { if (unlikely (i >= len)) return Null (Type); @@ -469,6 +515,20 @@ struct ArrayOf inline unsigned int get_size (void) const { return len.static_size + len * Type::static_size; } + inline hb_array_t<Type> as_array (void) + { return hb_array (arrayZ, len); } + inline hb_array_t<const Type> as_array (void) const + { return hb_array (arrayZ, len); } + + inline hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + inline bool serialize (hb_serialize_context_t *c, unsigned int items_len) { @@ -528,20 +588,15 @@ struct ArrayOf return_trace (true); } - template <typename SearchType> - inline int lsearch (const SearchType &x) const - { - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (!this->arrayZ[i].cmp (x)) - return i; - return -1; - } + template <typename T> + inline Type &lsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().lsearch (x, ¬_found); } + template <typename T> + inline const Type &lsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().lsearch (x, ¬_found); } - inline void qsort (void) - { - ::qsort (arrayZ, len, sizeof (Type), Type::cmp); - } + inline void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1) + { as_array ().qsort (start, end); } inline bool sanitize_shallow (hb_sanitize_context_t *c) const { @@ -723,22 +778,31 @@ struct ArrayOfM1 template <typename Type, typename LenType=HBUINT16> struct SortedArrayOf : ArrayOf<Type, LenType> { - template <typename SearchType> - inline int bsearch (const SearchType &x) const - { - /* Hand-coded bsearch here since this is in the hot inner loop. */ - const Type *arr = this->arrayZ; - int min = 0, max = (int) this->len - 1; - while (min <= max) - { - int mid = ((unsigned int) min + (unsigned int) max) / 2; - int c = arr[mid].cmp (x); - if (c < 0) max = mid - 1; - else if (c > 0) min = mid + 1; - else return mid; - } - return -1; - } + inline hb_sorted_array_t<Type> as_array (void) + { return hb_sorted_array (this->arrayZ, this->len); } + inline hb_sorted_array_t<const Type> as_array (void) const + { return hb_sorted_array (this->arrayZ, this->len); } + + inline hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) const + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count) + { return as_array ().sub_array (start_offset, count);} + inline hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count /* IN/OUT */) + { return as_array ().sub_array (start_offset, count);} + + template <typename T> + inline Type &bsearch (const T &x, Type ¬_found = Crap (Type)) + { return *as_array ().bsearch (x, ¬_found); } + template <typename T> + inline const Type &bsearch (const T &x, const Type ¬_found = Null (Type)) const + { return *as_array ().bsearch (x, ¬_found); } + template <typename T> + inline bool bfind (const T &x, unsigned int *i = nullptr, + hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE, + unsigned int to_store = (unsigned int) -1) const + { return as_array ().bfind (x, i, not_found, to_store); } }; /* @@ -810,15 +874,36 @@ struct VarSizedBinSearchArrayOf HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (VarSizedBinSearchArrayOf, Type); + inline bool last_is_terminator (void) const + { + if (unlikely (!header.nUnits)) return false; + + /* Gah. + * + * "The number of termination values that need to be included is table-specific. + * The value that indicates binary search termination is 0xFFFF." */ + const HBUINT16 *words = &StructAtOffset<HBUINT16> (&bytesZ, (header.nUnits - 1) * header.unitSize); + unsigned int count = Type::TerminationWordCount; + for (unsigned int i = 0; i < count; i++) + if (words[i] != 0xFFFFu) + return false; + return true; + } + inline const Type& operator [] (unsigned int i) const { - if (unlikely (i >= header.nUnits)) return Null (Type); + if (unlikely (i >= get_length ())) return Null (Type); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } inline Type& operator [] (unsigned int i) { + if (unlikely (i >= get_length ())) return Crap (Type); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } + inline unsigned int get_length (void) const + { + return header.nUnits - last_is_terminator (); + } inline unsigned int get_size (void) const { return header.static_size + header.nUnits * header.unitSize; } @@ -842,7 +927,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base))) return_trace (false); @@ -853,7 +938,7 @@ struct VarSizedBinSearchArrayOf { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = header.nUnits; + unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) if (unlikely (!(*this)[i].sanitize (c, base, user_data))) return_trace (false); @@ -864,7 +949,7 @@ struct VarSizedBinSearchArrayOf inline const Type *bsearch (const T &key) const { unsigned int size = header.unitSize; - int min = 0, max = (int) header.nUnits - 1; + int min = 0, max = (int) get_length () - 1; while (min <= max) { int mid = ((unsigned int) min + (unsigned int) max) / 2; |