summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-open-type.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type.hh243
1 files changed, 144 insertions, 99 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
index 7e524177f6..6967bca3d4 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type.hh
@@ -33,6 +33,7 @@
#include "hb-blob.hh"
#include "hb-face.hh"
#include "hb-machinery.hh"
+#include "hb-meta.hh"
#include "hb-subset.hh"
@@ -104,7 +105,7 @@ struct IntType
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this)));
+ return_trace (c->check_struct (this));
}
protected:
BEInt<Type, Size> v;
@@ -140,27 +141,29 @@ typedef HBINT32 FWORD32;
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
typedef HBUINT16 UFWORD;
-/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
-struct F2DOT14 : HBINT16
+template <typename Type, unsigned fraction_bits>
+struct HBFixed : Type
{
- F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; }
- // 16384 means 1<<14
- float to_float () const { return ((int32_t) v) / 16384.f; }
- void set_float (float f) { v = roundf (f * 16384.f); }
+ static constexpr float shift = (float) (1 << fraction_bits);
+ static_assert (Type::static_size * 8 > fraction_bits, "");
+
+ operator signed () const = delete;
+ operator unsigned () const = delete;
+ typename Type::type to_int () const { return Type::v; }
+ void set_int (typename Type::type i ) { Type::v = i; }
+ float to_float (float offset = 0) const { return ((int32_t) Type::v + offset) / shift; }
+ void set_float (float f) { Type::v = roundf (f * shift); }
public:
- DEFINE_SIZE_STATIC (2);
+ DEFINE_SIZE_STATIC (Type::static_size);
};
+/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
+using F2DOT14 = HBFixed<HBINT16, 14>;
+using F4DOT12 = HBFixed<HBINT16, 12>;
+using F6DOT10 = HBFixed<HBINT16, 10>;
+
/* 32-bit signed fixed-point number (16.16). */
-struct HBFixed : HBINT32
-{
- HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
- // 65536 means 1<<16
- float to_float () const { return ((int32_t) v) / 65536.f; }
- void set_float (float f) { v = roundf (f * 65536.f); }
- public:
- DEFINE_SIZE_STATIC (4);
-};
+using F16DOT16 = HBFixed<HBINT32, 16>;
/* Date represented in number of seconds since 12:00 midnight, January 1,
* 1904. The value is represented as a signed 64-bit integer. */
@@ -169,7 +172,7 @@ struct LONGDATETIME
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (likely (c->check_struct (this)));
+ return_trace (c->check_struct (this));
}
protected:
HBINT32 major;
@@ -195,6 +198,10 @@ struct HBGlyphID16 : HBUINT16
{
HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
};
+struct HBGlyphID24 : HBUINT24
+{
+ HBGlyphID24& operator = (uint32_t i) { HBUINT24::operator= (i); return *this; }
+};
/* Script/language-system/feature index */
struct Index : HBUINT16 {
@@ -207,6 +214,12 @@ typedef Index NameID;
struct VarIdx : HBUINT32 {
static constexpr unsigned NO_VARIATION = 0xFFFFFFFFu;
+ static_assert (NO_VARIATION == HB_OT_LAYOUT_NO_VARIATIONS_INDEX, "");
+ static uint32_t add (uint32_t i, unsigned short v)
+ {
+ if (i == NO_VARIATION) return i;
+ return i + v;
+ }
VarIdx& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
};
DECLARE_NULL_NAMESPACE_BYTES (OT, VarIdx);
@@ -296,9 +309,15 @@ struct _hb_has_null<Type, true>
static Type *get_crap () { return &Crap (Type); }
};
-template <typename Type, typename OffsetType, bool has_null=true>
+template <typename Type, typename OffsetType, typename BaseType=void, bool has_null=true>
struct OffsetTo : Offset<OffsetType, has_null>
{
+ using target_t = Type;
+
+ // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time.
+ static_assert (has_null == false ||
+ (hb_has_null_size (Type) || !hb_has_min_size (Type)), "");
+
HB_DELETE_COPY_ASSIGN (OffsetTo);
OffsetTo () = default;
@@ -316,22 +335,22 @@ struct OffsetTo : Offset<OffsetType, has_null>
}
template <typename Base,
- hb_enable_if (hb_is_convertible (const Base, const void *))>
+ hb_enable_if (hb_is_convertible (const Base, const BaseType *))>
friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
template <typename Base,
- hb_enable_if (hb_is_convertible (const Base, const void *))>
+ hb_enable_if (hb_is_convertible (const Base, const BaseType *))>
friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
template <typename Base,
- hb_enable_if (hb_is_convertible (Base, void *))>
+ hb_enable_if (hb_is_convertible (Base, BaseType *))>
friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
template <typename Base,
- hb_enable_if (hb_is_convertible (Base, void *))>
+ hb_enable_if (hb_is_convertible (Base, BaseType *))>
friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
- template <typename ...Ts>
+ template <typename Base, typename ...Ts>
bool serialize_subset (hb_subset_context_t *c, const OffsetTo& src,
- const void *src_base, Ts&&... ds)
+ const Base *src_base, Ts&&... ds)
{
*this = 0;
if (src.is_null ())
@@ -395,20 +414,25 @@ struct OffsetTo : Offset<OffsetType, has_null>
const void *src_base, unsigned dst_bias = 0)
{ return serialize_copy (c, src, src_base, dst_bias, hb_serialize_context_t::Head); }
- bool sanitize_shallow (hb_sanitize_context_t *c, const void *base) const
+ bool sanitize_shallow (hb_sanitize_context_t *c, const BaseType *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this))) return_trace (false);
- if (unlikely (this->is_null ())) return_trace (true);
+ hb_barrier ();
+ //if (unlikely (this->is_null ())) return_trace (true);
if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false);
return_trace (true);
}
template <typename ...Ts>
- bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
+#ifndef HB_OPTIMIZE_SIZE
+ HB_ALWAYS_INLINE
+#endif
+ bool sanitize (hb_sanitize_context_t *c, const BaseType *base, Ts&&... ds) const
{
TRACE_SANITIZE (this);
return_trace (sanitize_shallow (c, base) &&
+ hb_barrier () &&
(this->is_null () ||
c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) ||
neuter (c)));
@@ -423,14 +447,14 @@ struct OffsetTo : Offset<OffsetType, has_null>
DEFINE_SIZE_STATIC (sizeof (OffsetType));
};
/* Partial specializations. */
-template <typename Type, bool has_null=true> using Offset16To = OffsetTo<Type, HBUINT16, has_null>;
-template <typename Type, bool has_null=true> using Offset24To = OffsetTo<Type, HBUINT24, has_null>;
-template <typename Type, bool has_null=true> using Offset32To = OffsetTo<Type, HBUINT32, has_null>;
+template <typename Type, typename BaseType=void, bool has_null=true> using Offset16To = OffsetTo<Type, HBUINT16, BaseType, has_null>;
+template <typename Type, typename BaseType=void, bool has_null=true> using Offset24To = OffsetTo<Type, HBUINT24, BaseType, has_null>;
+template <typename Type, typename BaseType=void, bool has_null=true> using Offset32To = OffsetTo<Type, HBUINT32, BaseType, has_null>;
-template <typename Type, typename OffsetType> using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
-template <typename Type> using NNOffset16To = Offset16To<Type, false>;
-template <typename Type> using NNOffset24To = Offset24To<Type, false>;
-template <typename Type> using NNOffset32To = Offset32To<Type, false>;
+template <typename Type, typename OffsetType, typename BaseType=void> using NNOffsetTo = OffsetTo<Type, OffsetType, BaseType, false>;
+template <typename Type, typename BaseType=void> using NNOffset16To = Offset16To<Type, BaseType, false>;
+template <typename Type, typename BaseType=void> using NNOffset24To = Offset24To<Type, BaseType, false>;
+template <typename Type, typename BaseType=void> using NNOffset32To = Offset32To<Type, BaseType, false>;
/*
@@ -445,22 +469,16 @@ struct UnsizedArrayOf
HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
- const Type& operator [] (int i_) const
+ const Type& operator [] (unsigned int i) const
{
- unsigned int i = (unsigned int) i_;
- const Type *p = &arrayZ[i];
- if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */
- return *p;
+ return arrayZ[i];
}
- Type& operator [] (int i_)
+ Type& operator [] (unsigned int i)
{
- unsigned int i = (unsigned int) i_;
- Type *p = &arrayZ[i];
- if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */
- return *p;
+ return arrayZ[i];
}
- unsigned int get_size (unsigned int len) const
+ static unsigned int get_size (unsigned int len)
{ return len * Type::static_size; }
template <typename T> operator T * () { return arrayZ; }
@@ -485,10 +503,10 @@ struct UnsizedArrayOf
void qsort (unsigned int len, unsigned int start = 0, unsigned int end = (unsigned int) -1)
{ as_array (len).qsort (start, end); }
- bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+ bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
- if (unlikely (!c->extend (this, items_len))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (items_len), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
@@ -496,8 +514,8 @@ struct UnsizedArrayOf
bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -514,11 +532,13 @@ struct UnsizedArrayOf
}
template <typename ...Ts>
+ HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
- if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+ if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
+ hb_barrier ();
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
return_trace (false);
@@ -538,25 +558,27 @@ struct UnsizedArrayOf
};
/* Unsized array of offset's */
-template <typename Type, typename OffsetType, bool has_null=true>
-using UnsizedArray16OfOffsetTo = UnsizedArrayOf<OffsetTo<Type, OffsetType, has_null>>;
+template <typename Type, typename OffsetType, typename BaseType=void, bool has_null=true>
+using UnsizedArray16OfOffsetTo = UnsizedArrayOf<OffsetTo<Type, OffsetType, BaseType, has_null>>;
/* Unsized array of offsets relative to the beginning of the array itself. */
-template <typename Type, typename OffsetType, bool has_null=true>
-struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
+template <typename Type, typename OffsetType, typename BaseType=void, bool has_null=true>
+struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, BaseType, has_null>
{
const Type& operator [] (int i_) const
{
unsigned int i = (unsigned int) i_;
- const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i];
- if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */
+ const OffsetTo<Type, OffsetType, BaseType, has_null> *p = &this->arrayZ[i];
+ if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */
+ _hb_compiler_memory_r_barrier ();
return this+*p;
}
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
- const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i];
- if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */
+ const OffsetTo<Type, OffsetType, BaseType, has_null> *p = &this->arrayZ[i];
+ if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */
+ _hb_compiler_memory_r_barrier ();
return this+*p;
}
@@ -564,7 +586,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_
bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
{
TRACE_SANITIZE (this);
- return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
+ return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, BaseType, has_null>
::sanitize (c, count, this, std::forward<Ts> (ds)...)));
}
};
@@ -607,12 +629,14 @@ struct ArrayOf
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= len)) return Null (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i];
}
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= len)) return Crap (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i];
}
@@ -634,14 +658,9 @@ struct ArrayOf
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count); }
- hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count); }
+ /* Faster range-based for loop. */
+ const Type *begin () const { return arrayZ; }
+ const Type *end () const { return arrayZ + len; }
template <typename T>
Type &lsearch (const T &x, Type &not_found = Crap (Type))
@@ -655,15 +674,15 @@ struct ArrayOf
unsigned int to_store = (unsigned int) -1) const
{ return as_array ().lfind (x, i, not_found, to_store); }
- void qsort (unsigned int start = 0, unsigned int end = (unsigned int) -1)
- { as_array ().qsort (start, end); }
+ void qsort ()
+ { as_array ().qsort (); }
- HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len)
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
c->check_assign (len, items_len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend (this))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
@@ -671,8 +690,8 @@ struct ArrayOf
HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -703,11 +722,13 @@ struct ArrayOf
}
template <typename ...Ts>
+ HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+ if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
+ hb_barrier ();
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -718,7 +739,9 @@ struct ArrayOf
bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
+ return_trace (len.sanitize (c) &&
+ hb_barrier () &&
+ c->check_array_sized (arrayZ, len, sizeof (LenType)));
}
public:
@@ -728,6 +751,7 @@ struct ArrayOf
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>;
+template <typename Type> using Array24Of = ArrayOf<Type, HBUINT24>;
template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>;
using PString = ArrayOf<HBUINT8, HBUINT8>;
@@ -737,26 +761,28 @@ template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUI
template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
/* Array of offsets relative to the beginning of the array itself. */
-template <typename Type>
-struct List16OfOffset16To : Array16OfOffset16To<Type>
+template <typename Type, typename OffsetType>
+struct List16OfOffsetTo : ArrayOf<OffsetTo<Type, OffsetType>, HBUINT16>
{
const Type& operator [] (int i_) const
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= this->len)) return Null (Type);
+ _hb_compiler_memory_r_barrier ();
return this+this->arrayZ[i];
}
const Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= this->len)) return Crap (Type);
+ _hb_compiler_memory_r_barrier ();
return this+this->arrayZ[i];
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
- struct List16OfOffset16To<Type> *out = c->serializer->embed (*this);
+ struct List16OfOffsetTo *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
unsigned int count = this->len;
for (unsigned int i = 0; i < count; i++)
@@ -768,12 +794,15 @@ struct List16OfOffset16To : Array16OfOffset16To<Type>
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
- return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...));
+ return_trace ((Array16Of<OffsetTo<Type, OffsetType>>::sanitize (c, this, std::forward<Ts> (ds)...)));
}
};
+template <typename Type>
+using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>;
+
/* An array starting at second element. */
-template <typename Type, typename LenType=HBUINT16>
+template <typename Type, typename LenType>
struct HeadlessArrayOf
{
static constexpr unsigned item_size = Type::static_size;
@@ -784,12 +813,14 @@ struct HeadlessArrayOf
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= lenP1 || !i)) return Null (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i-1];
}
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= lenP1 || !i)) return Crap (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i-1];
}
unsigned int get_size () const
@@ -808,21 +839,25 @@ struct HeadlessArrayOf
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- bool serialize (hb_serialize_context_t *c, unsigned int items_len)
+ /* Faster range-based for loop. */
+ const Type *begin () const { return arrayZ; }
+ const Type *end () const { return arrayZ + get_length (); }
+
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, unsigned int items_len, bool clear = true)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
c->check_assign (lenP1, items_len + 1, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW);
- if (unlikely (!c->extend (this))) return_trace (false);
+ if (unlikely (!c->extend_size (this, get_size (), clear))) return_trace (false);
return_trace (true);
}
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, Type))>
- bool serialize (hb_serialize_context_t *c, Iterator items)
+ HB_NODISCARD bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
- unsigned count = items.len ();
- if (unlikely (!serialize (c, count))) return_trace (false);
+ unsigned count = hb_len (items);
+ if (unlikely (!serialize (c, count, false))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
@@ -831,11 +866,13 @@ struct HeadlessArrayOf
}
template <typename ...Ts>
+ HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+ if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
+ hb_barrier ();
unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -848,7 +885,8 @@ struct HeadlessArrayOf
{
TRACE_SANITIZE (this);
return_trace (lenP1.sanitize (c) &&
- (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
+ hb_barrier () &&
+ (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType))));
}
public:
@@ -857,6 +895,7 @@ struct HeadlessArrayOf
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
+template <typename Type> using HeadlessArray16Of = HeadlessArrayOf<Type, HBUINT16>;
/* An array storing length-1. */
template <typename Type, typename LenType=HBUINT16>
@@ -868,23 +907,27 @@ struct ArrayOfM1
{
unsigned int i = (unsigned int) i_;
if (unlikely (i > lenM1)) return Null (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i];
}
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i > lenM1)) return Crap (Type);
+ _hb_compiler_memory_r_barrier ();
return arrayZ[i];
}
unsigned int get_size () const
{ return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
template <typename ...Ts>
+ HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+ if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
+ hb_barrier ();
unsigned int count = lenM1 + 1;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
@@ -897,7 +940,8 @@ struct ArrayOfM1
{
TRACE_SANITIZE (this);
return_trace (lenM1.sanitize (c) &&
- (c->check_array (arrayZ, lenM1 + 1)));
+ hb_barrier () &&
+ (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType))));
}
public:
@@ -922,14 +966,9 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
- hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int count) const
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<const Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */) const
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int count)
- { return as_array ().sub_array (start_offset, count); }
- hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *count = nullptr /* IN/OUT */)
- { return as_array ().sub_array (start_offset, count); }
+ /* Faster range-based for loop. */
+ const Type *begin () const { return this->arrayZ; }
+ const Type *end () const { return this->arrayZ + this->len; }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
@@ -960,6 +999,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
};
template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>;
+template <typename Type> using SortedArray24Of = SortedArrayOf<Type, HBUINT24>;
template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>;
/*
@@ -1052,12 +1092,14 @@ struct VarSizedBinSearchArrayOf
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= get_length ())) return Null (Type);
+ _hb_compiler_memory_r_barrier ();
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= get_length ())) return Crap (Type);
+ _hb_compiler_memory_r_barrier ();
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
}
unsigned int get_length () const
@@ -1066,11 +1108,13 @@ struct VarSizedBinSearchArrayOf
{ return header.static_size + header.nUnits * header.unitSize; }
template <typename ...Ts>
+ HB_ALWAYS_INLINE
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
- if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
+ if (!sizeof... (Ts) && hb_is_trivially_copyable(Type)) return_trace (true);
+ hb_barrier ();
unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
@@ -1097,6 +1141,7 @@ struct VarSizedBinSearchArrayOf
{
TRACE_SANITIZE (this);
return_trace (header.sanitize (c) &&
+ hb_barrier () &&
Type::static_size <= header.unitSize &&
c->check_range (bytesZ.arrayZ,
header.nUnits,