summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh263
1 files changed, 162 insertions, 101 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh
index 5d33199e128..8180287d494 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-open-type-private.hh
@@ -31,6 +31,7 @@
#include "hb-private.hh"
#include "hb-debug.hh"
+#include "hb-blob-private.hh"
#include "hb-face-private.hh"
@@ -127,46 +128,6 @@ static inline Type& StructAfter(TObject &X)
/*
- * Null objects
- */
-
-/* Global nul-content Null pool. Enlarge as necessary. */
-
-#define HB_NULL_POOL_SIZE 264
-static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
-
-#ifdef HB_NO_VISIBILITY
-static
-#else
-extern HB_INTERNAL
-#endif
-const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)]
-#ifdef HB_NO_VISIBILITY
-= {}
-#endif
-;
-
-/* Generic nul-content Null objects. */
-template <typename Type>
-static inline const Type& Null (void) {
- static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
- return *CastP<Type> (_hb_NullPool);
-}
-
-/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
-#define DEFINE_NULL_DATA(Type, data) \
-static const char _Null##Type[sizeof (Type) + 1] = data; /* +1 is for nul-termination in data */ \
-template <> \
-/*static*/ inline const Type& Null<Type> (void) { \
- return *CastP<Type> (_Null##Type); \
-} /* The following line really exists such that we end in a place needing semicolon */ \
-static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.")
-
-/* Accessor macro. */
-#define Null(Type) Null<Type>()
-
-
-/*
* Dispatch
*/
@@ -225,7 +186,7 @@ struct hb_sanitize_context_t :
inline void start_processing (void)
{
this->start = hb_blob_get_data (this->blob, nullptr);
- this->end = this->start + hb_blob_get_length (this->blob);
+ this->end = this->start + this->blob->length;
assert (this->start <= this->end); /* Must not overflow. */
this->max_ops = MAX ((unsigned int) (this->end - this->start) * HB_SANITIZE_MAX_OPS_FACTOR,
(unsigned) HB_SANITIZE_MAX_OPS_MIN);
@@ -288,7 +249,7 @@ struct hb_sanitize_context_t :
return likely (this->check_range (obj, obj->min_size));
}
- inline bool may_edit (const void *base HB_UNUSED, unsigned int len HB_UNUSED)
+ inline bool may_edit (const void *base, unsigned int len)
{
if (this->edit_count >= HB_SANITIZE_MAX_EDITS)
return false;
@@ -368,7 +329,7 @@ struct Sanitizer
unsigned int edit_count = c->edit_count;
if (edit_count && !c->writable) {
c->start = hb_blob_get_data_writable (blob, nullptr);
- c->end = c->start + hb_blob_get_length (blob);
+ c->end = c->start + blob->length;
if (c->start) {
c->writable = true;
@@ -383,19 +344,17 @@ struct Sanitizer
DEBUG_MSG_FUNC (SANITIZE, c->start, sane ? "PASSED" : "FAILED");
if (sane)
+ {
+ blob->lock ();
return blob;
- else {
+ }
+ else
+ {
hb_blob_destroy (blob);
return hb_blob_get_empty ();
}
}
- static const Type* lock_instance (hb_blob_t *blob) {
- hb_blob_make_immutable (blob);
- const char *base = hb_blob_get_data (blob, nullptr);
- return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
- }
-
inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
private:
@@ -672,7 +631,7 @@ typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */
typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */
typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */
typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */
-typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
+typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
typedef HBINT16 FWORD;
@@ -683,17 +642,19 @@ typedef HBUINT16 UFWORD;
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
struct F2DOT14 : HBINT16
{
- //inline float to_float (void) const { return ???; }
- //inline void set_float (float f) { v.set (f * ???); }
+ // 16384 means 1<<14
+ inline float to_float (void) const { return ((int32_t) v) / 16384.f; }
+ inline void set_float (float f) { v.set (round (f * 16384.f)); }
public:
DEFINE_SIZE_STATIC (2);
};
/* 32-bit signed fixed-point number (16.16). */
-struct Fixed: HBINT32
+struct Fixed : HBINT32
{
- inline float to_float (void) const { return ((int32_t) v) / 65536.0; }
- inline void set_float (float f) { v.set (round (f * 65536.0)); }
+ // 65536 means 1<<16
+ inline float to_float (void) const { return ((int32_t) v) / 65536.f; }
+ inline void set_float (float f) { v.set (round (f * 65536.f)); }
public:
DEFINE_SIZE_STATIC (4);
};
@@ -724,16 +685,19 @@ struct Tag : HBUINT32
public:
DEFINE_SIZE_STATIC (4);
};
-DEFINE_NULL_DATA (Tag, " ");
+DEFINE_NULL_DATA (OT, Tag, " ");
/* Glyph index number, same as uint16 (length = 16 bits) */
typedef HBUINT16 GlyphID;
+/* Name-table index, same as uint16 (length = 16 bits) */
+typedef HBUINT16 NameID;
+
/* Script/language-system/feature index */
struct Index : HBUINT16 {
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
};
-DEFINE_NULL_DATA (Index, "\xff\xff");
+DEFINE_NULL_DATA (OT, Index, "\xff\xff");
/* Offset, Null offset = 0 */
template <typename Type>
@@ -815,6 +779,12 @@ struct OffsetTo : Offset<OffsetType>
{
unsigned int offset = *this;
if (unlikely (!offset)) return Null(Type);
+ return StructAtOffset<const Type> (base, offset);
+ }
+ inline Type& operator () (void *base) const
+ {
+ unsigned int offset = *this;
+ if (unlikely (!offset)) return Crap(Type);
return StructAtOffset<Type> (base, offset);
}
@@ -862,6 +832,89 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
* Array Types
*/
+
+/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
+template <typename Type>
+struct UnsizedArrayOf
+{
+ inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
+ inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+
+ /* Note: for structs that do not reference other structs,
+ * we do not need to call their sanitize() as we already did
+ * a bound check on the aggregate array size. We just include
+ * a small unreachable expression to make sure the structs
+ * pointed to do have a simple sanitize(), ie. they do not
+ * reference other structs via offsets.
+ */
+ (void) (false && arrayZ[0].sanitize (c));
+
+ return_trace (true);
+ }
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!arrayZ[i].sanitize (c, base)))
+ return_trace (false);
+ return_trace (true);
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
+ {
+ TRACE_SANITIZE (this);
+ if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
+ for (unsigned int i = 0; i < count; i++)
+ if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
+ return_trace (false);
+ return_trace (true);
+ }
+
+ inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
+ }
+
+ public:
+ Type arrayZ[VAR];
+ public:
+ DEFINE_SIZE_ARRAY (0, arrayZ);
+};
+
+/* Unsized array of offset's */
+template <typename Type, typename OffsetType>
+struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
+
+/* Unsized array of offsets relative to the beginning of the array itself. */
+template <typename Type, typename OffsetType>
+struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
+{
+ inline const Type& operator [] (unsigned int i) const
+ {
+ return this+this->arrayZ[i];
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
+ }
+ template <typename T>
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
+ }
+};
+
+
/* An array with a number of elements. */
template <typename Type, typename LenType=HBUINT16>
struct ArrayOf
@@ -875,17 +928,18 @@ struct ArrayOf
count -= start_offset;
count = MIN (count, *pcount);
*pcount = count;
- return array + start_offset;
+ return arrayZ + start_offset;
}
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= len)) return Null(Type);
- return array[i];
+ return arrayZ[i];
}
inline Type& operator [] (unsigned int i)
{
- return array[i];
+ if (unlikely (i >= len)) return Crap(Type);
+ return arrayZ[i];
}
inline unsigned int get_size (void) const
{ return len.static_size + len * Type::static_size; }
@@ -907,7 +961,7 @@ struct ArrayOf
TRACE_SERIALIZE (this);
if (unlikely (!serialize (c, items_len))) return_trace (false);
for (unsigned int i = 0; i < items_len; i++)
- array[i] = items[i];
+ arrayZ[i] = items[i];
items += items_len;
return_trace (true);
}
@@ -924,7 +978,7 @@ struct ArrayOf
* pointed to do have a simple sanitize(), ie. they do not
* reference other structs via offsets.
*/
- (void) (false && array[0].sanitize (c));
+ (void) (false && arrayZ[0].sanitize (c));
return_trace (true);
}
@@ -934,7 +988,7 @@ struct ArrayOf
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
- if (unlikely (!array[i].sanitize (c, base)))
+ if (unlikely (!arrayZ[i].sanitize (c, base)))
return_trace (false);
return_trace (true);
}
@@ -945,7 +999,7 @@ struct ArrayOf
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
- if (unlikely (!array[i].sanitize (c, base, user_data)))
+ if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
return_trace (false);
return_trace (true);
}
@@ -955,28 +1009,28 @@ struct ArrayOf
{
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
- if (!this->array[i].cmp (x))
+ if (!this->arrayZ[i].cmp (x))
return i;
return -1;
}
inline void qsort (void)
{
- ::qsort (array, len, sizeof (Type), Type::cmp);
+ ::qsort (arrayZ, len, sizeof (Type), Type::cmp);
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
+ return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
}
public:
LenType len;
- Type array[VAR];
+ Type arrayZ[VAR];
public:
- DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+ DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
@@ -991,7 +1045,12 @@ struct OffsetListOf : OffsetArrayOf<Type>
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= this->len)) return Null(Type);
- return this+this->array[i];
+ return this+this->arrayZ[i];
+ }
+ inline const Type& operator [] (unsigned int i)
+ {
+ if (unlikely (i >= this->len)) return Crap(Type);
+ return this+this->arrayZ[i];
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -1015,7 +1074,12 @@ struct HeadlessArrayOf
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= len || !i)) return Null(Type);
- return array[i-1];
+ return arrayZ[i-1];
+ }
+ inline Type& operator [] (unsigned int i)
+ {
+ if (unlikely (i >= len || !i)) return Crap(Type);
+ return arrayZ[i-1];
}
inline unsigned int get_size (void) const
{ return len.static_size + (len ? len - 1 : 0) * Type::static_size; }
@@ -1030,7 +1094,7 @@ struct HeadlessArrayOf
if (unlikely (!items_len)) return_trace (true);
if (unlikely (!c->extend (*this))) return_trace (false);
for (unsigned int i = 0; i < items_len - 1; i++)
- array[i] = items[i];
+ arrayZ[i] = items[i];
items += items_len - 1;
return_trace (true);
}
@@ -1047,7 +1111,7 @@ struct HeadlessArrayOf
* pointed to do have a simple sanitize(), ie. they do not
* reference other structs via offsets.
*/
- (void) (false && array[0].sanitize (c));
+ (void) (false && arrayZ[0].sanitize (c));
return_trace (true);
}
@@ -1057,14 +1121,14 @@ struct HeadlessArrayOf
{
TRACE_SANITIZE (this);
return_trace (len.sanitize (c) &&
- (!len || c->check_array (array, Type::static_size, len - 1)));
+ (!len || c->check_array (arrayZ, Type::static_size, len - 1)));
}
public:
LenType len;
- Type array[VAR];
+ Type arrayZ[VAR];
public:
- DEFINE_SIZE_ARRAY (sizeof (LenType), array);
+ DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
@@ -1078,7 +1142,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
inline int bsearch (const SearchType &x) const
{
/* Hand-coded bsearch here since this is in the hot inner loop. */
- const Type *arr = this->array;
+ const Type *arr = this->arrayZ;
int min = 0, max = (int) this->len - 1;
while (min <= max)
{
@@ -1113,18 +1177,18 @@ struct BinSearchHeader
{
len.set (v);
assert (len == v);
- entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1);
- searchRangeZ.set (16 * (1u << entrySelectorZ));
- rangeShiftZ.set (v * 16 > searchRangeZ
- ? 16 * v - searchRangeZ
- : 0);
+ entrySelector.set (MAX (1u, _hb_bit_storage (v)) - 1);
+ searchRange.set (16 * (1u << entrySelector));
+ rangeShift.set (v * 16 > searchRange
+ ? 16 * v - searchRange
+ : 0);
}
protected:
HBUINT16 len;
- HBUINT16 searchRangeZ;
- HBUINT16 entrySelectorZ;
- HBUINT16 rangeShiftZ;
+ HBUINT16 searchRange;
+ HBUINT16 entrySelector;
+ HBUINT16 rangeShift;
public:
DEFINE_SIZE_STATIC (8);
@@ -1136,7 +1200,7 @@ struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
/* Lazy struct and blob loaders. */
-/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
template <typename T>
struct hb_lazy_loader_t
{
@@ -1148,7 +1212,7 @@ struct hb_lazy_loader_t
inline void fini (void)
{
- if (instance && instance != &OT::Null(T))
+ if (instance && instance != &Null(T))
{
instance->fini();
free (instance);
@@ -1163,12 +1227,12 @@ struct hb_lazy_loader_t
{
p = (T *) calloc (1, sizeof (T));
if (unlikely (!p))
- p = const_cast<T *> (&OT::Null(T));
+ p = const_cast<T *> (&Null(T));
else
p->init (face);
if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
{
- if (p != &OT::Null(T))
+ if (p != &Null(T))
p->fini ();
goto retry;
}
@@ -1186,15 +1250,14 @@ struct hb_lazy_loader_t
T *instance;
};
-/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+/* Logic is shared between hb_lazy_loader_t and hb_table_lazy_loader_t */
template <typename T>
-struct hb_lazy_table_loader_t
+struct hb_table_lazy_loader_t
{
inline void init (hb_face_t *face_)
{
face = face_;
blob = nullptr;
- instance = nullptr;
}
inline void fini (void)
@@ -1205,19 +1268,18 @@ struct hb_lazy_table_loader_t
inline const T* get (void) const
{
retry:
- T *p = (T *) hb_atomic_ptr_get (&instance);
- if (unlikely (!p))
+ hb_blob_t *blob_ = (hb_blob_t *) hb_atomic_ptr_get (&blob);
+ if (unlikely (!blob_))
{
- hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
- p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
- if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
+ blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
+ if (!hb_atomic_ptr_cmpexch (&blob, nullptr, blob_))
{
hb_blob_destroy (blob_);
goto retry;
}
blob = blob_;
}
- return p;
+ return blob_->as<T> ();
}
inline const T* operator-> (void) const
@@ -1225,10 +1287,9 @@ struct hb_lazy_table_loader_t
return get();
}
+ private:
hb_face_t *face;
mutable hb_blob_t *blob;
- private:
- mutable T *instance;
};