Bug 1554306 - Update HarfBuzz to version 2.5.1. r=jfkthame
Differential Revision: https://phabricator.services.mozilla.com/D32776
This commit is contained in:
@@ -28,7 +28,7 @@
|
||||
#define HB_ARRAY_HH
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-dsalgs.hh"
|
||||
#include "hb-algs.hh"
|
||||
#include "hb-iter.hh"
|
||||
#include "hb-null.hh"
|
||||
|
||||
@@ -37,22 +37,31 @@ template <typename Type>
|
||||
struct hb_sorted_array_t;
|
||||
|
||||
template <typename Type>
|
||||
struct hb_array_t :
|
||||
hb_iter_t<hb_array_t<Type>, Type>,
|
||||
hb_iter_mixin_t<hb_array_t<Type>, Type>
|
||||
struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
{
|
||||
/*
|
||||
* Constructors.
|
||||
*/
|
||||
hb_array_t () : arrayZ (nullptr), length (0) {}
|
||||
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
|
||||
template <unsigned int length_> hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
|
||||
hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
|
||||
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
|
||||
template <unsigned int length_>
|
||||
hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
|
||||
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
hb_array_t (const hb_array_t<U> &o) :
|
||||
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
|
||||
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
hb_array_t& operator = (const hb_array_t<U> &o)
|
||||
{ arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
|
||||
|
||||
/*
|
||||
* Iterator implementation.
|
||||
*/
|
||||
typedef Type __item_type__;
|
||||
typedef Type& __item_t__;
|
||||
static constexpr bool is_random_access_iterator = true;
|
||||
Type& __item_at__ (unsigned i) const
|
||||
{
|
||||
if (unlikely (i >= length)) return CrapOrNull (Type);
|
||||
@@ -63,16 +72,25 @@ struct hb_array_t :
|
||||
if (unlikely (n > length))
|
||||
n = length;
|
||||
length -= n;
|
||||
backwards_length += n;
|
||||
arrayZ += n;
|
||||
}
|
||||
void __rewind__ (unsigned n)
|
||||
{
|
||||
if (unlikely (n > length))
|
||||
n = length;
|
||||
length -= n;
|
||||
if (unlikely (n > backwards_length))
|
||||
n = backwards_length;
|
||||
length += n;
|
||||
backwards_length -= n;
|
||||
arrayZ -= n;
|
||||
}
|
||||
unsigned __len__ () const { return length; }
|
||||
bool __random_access__ () const { return true; }
|
||||
/* Ouch. The operator== compares the contents of the array. For range-based for loops,
|
||||
* it's best if we can just compare arrayZ, though comparing contents is still fast,
|
||||
* but also would require that Type has operator==. As such, we optimize this operator
|
||||
* for range-based for loop and just compare arrayZ. No need to compare length, as we
|
||||
* assume we're only compared to .end(). */
|
||||
bool operator != (const hb_array_t& o) const
|
||||
{ return arrayZ != o.arrayZ; }
|
||||
|
||||
/* Extra operators.
|
||||
*/
|
||||
@@ -80,6 +98,9 @@ struct hb_array_t :
|
||||
operator hb_array_t<const Type> () { return hb_array_t<const Type> (arrayZ, length); }
|
||||
template <typename T> operator T * () const { return arrayZ; }
|
||||
|
||||
HB_INTERNAL bool operator == (const hb_array_t &o) const;
|
||||
HB_INTERNAL uint32_t hash () const;
|
||||
|
||||
/*
|
||||
* Compare, Sort, and Search.
|
||||
*/
|
||||
@@ -91,7 +112,7 @@ struct hb_array_t :
|
||||
return (int) a.length - (int) length;
|
||||
return hb_memcmp (a.arrayZ, arrayZ, get_size ());
|
||||
}
|
||||
static int cmp (const void *pa, const void *pb)
|
||||
HB_INTERNAL static int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
|
||||
hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
|
||||
@@ -131,7 +152,7 @@ struct hb_array_t :
|
||||
}
|
||||
void qsort (unsigned int start, unsigned int end)
|
||||
{
|
||||
end = MIN (end, length);
|
||||
end = hb_min (end, length);
|
||||
assert (start <= end);
|
||||
if (likely (start < end))
|
||||
::qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
|
||||
@@ -154,7 +175,7 @@ struct hb_array_t :
|
||||
else
|
||||
count -= start_offset;
|
||||
if (seg_count)
|
||||
count = *seg_count = MIN (count, *seg_count);
|
||||
count = *seg_count = hb_min (count, *seg_count);
|
||||
return hb_array_t<Type> (arrayZ + start_offset, count);
|
||||
}
|
||||
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
|
||||
@@ -164,6 +185,17 @@ struct hb_array_t :
|
||||
void free ()
|
||||
{ ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
|
||||
|
||||
template <typename hb_serialize_context_t>
|
||||
hb_array_t copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto* out = c->start_embed (arrayZ);
|
||||
if (unlikely (!c->extend_size (out, get_size ()))) return_trace (hb_array_t ());
|
||||
for (unsigned i = 0; i < length; i++)
|
||||
out[i] = arrayZ[i]; /* TODO: add version that calls c->copy() */
|
||||
return_trace (hb_array_t (out, length));
|
||||
}
|
||||
|
||||
template <typename hb_sanitize_context_t>
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{ return c->check_array (arrayZ, length); }
|
||||
@@ -175,6 +207,7 @@ struct hb_array_t :
|
||||
public:
|
||||
Type *arrayZ;
|
||||
unsigned int length;
|
||||
unsigned int backwards_length;
|
||||
};
|
||||
template <typename T> inline hb_array_t<T>
|
||||
hb_array (T *array, unsigned int length)
|
||||
@@ -183,7 +216,6 @@ template <typename T, unsigned int length_> inline hb_array_t<T>
|
||||
hb_array (T (&array_)[length_])
|
||||
{ return hb_array_t<T> (array_); }
|
||||
|
||||
|
||||
enum hb_bfind_not_found_t
|
||||
{
|
||||
HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
@@ -193,14 +225,32 @@ enum hb_bfind_not_found_t
|
||||
|
||||
template <typename Type>
|
||||
struct hb_sorted_array_t :
|
||||
hb_sorted_iter_t<hb_sorted_array_t<Type>, Type>,
|
||||
hb_array_t<Type>,
|
||||
hb_iter_mixin_t<hb_sorted_array_t<Type>, Type>
|
||||
hb_iter_t<hb_sorted_array_t<Type>, Type&>,
|
||||
hb_array_t<Type>
|
||||
{
|
||||
typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
|
||||
HB_ITER_USING (iter_base_t);
|
||||
static constexpr bool is_random_access_iterator = true;
|
||||
static constexpr bool is_sorted_iterator = true;
|
||||
|
||||
hb_sorted_array_t () : hb_array_t<Type> () {}
|
||||
hb_sorted_array_t (const hb_array_t<Type> &o) : hb_array_t<Type> (o) {}
|
||||
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
|
||||
template <unsigned int length_> hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
|
||||
template <unsigned int length_>
|
||||
hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
|
||||
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
hb_sorted_array_t (const hb_array_t<U> &o) :
|
||||
hb_iter_t<hb_sorted_array_t<Type>, Type&> (),
|
||||
hb_array_t<Type> (o) {}
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
hb_sorted_array_t& operator = (const hb_array_t<U> &o)
|
||||
{ hb_array_t<Type> (*this) = o; return *this; }
|
||||
|
||||
/* Iterator implementation. */
|
||||
bool operator != (const hb_sorted_array_t& o) const
|
||||
{ return this->arrayZ != o.arrayZ || this->length != o.length; }
|
||||
|
||||
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
|
||||
{ return hb_sorted_array_t<Type> (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
|
||||
@@ -269,9 +319,30 @@ template <typename T, unsigned int length_> inline hb_sorted_array_t<T>
|
||||
hb_sorted_array (T (&array_)[length_])
|
||||
{ return hb_sorted_array_t<T> (array_); }
|
||||
|
||||
template <typename T>
|
||||
bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
|
||||
{
|
||||
return length == o.length &&
|
||||
+ hb_zip (*this, o)
|
||||
| hb_map ([] (hb_pair_t<T&, T&> &&_) { return _.first == _.second; })
|
||||
| hb_all
|
||||
;
|
||||
}
|
||||
template <typename T>
|
||||
uint32_t hb_array_t<T>::hash () const
|
||||
{
|
||||
return
|
||||
+ hb_iter (*this)
|
||||
| hb_map (hb_hash)
|
||||
| hb_reduce ([] (uint32_t a, uint32_t b) { return a * 31 + b; }, 0)
|
||||
;
|
||||
}
|
||||
|
||||
typedef hb_array_t<const char> hb_bytes_t;
|
||||
typedef hb_array_t<const unsigned char> hb_ubytes_t;
|
||||
|
||||
/* TODO Specialize opeator==/hash() for hb_bytes_t and hb_ubytes_t. */
|
||||
//template <>
|
||||
//uint32_t hb_array_t<const char>::hash () const { return 0; }
|
||||
|
||||
#endif /* HB_ARRAY_HH */
|
||||
|
||||
Reference in New Issue
Block a user