diff options
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.hh | 263 |
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; }; |