summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh277
1 files changed, 197 insertions, 80 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
index 2cc1fb20d2..2f4e1b9e9e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-open-type-private.hh
@@ -30,6 +30,8 @@
#define HB_OPEN_TYPE_PRIVATE_HH
#include "hb-private.hh"
+#include "hb-debug.hh"
+#include "hb-face-private.hh"
namespace OT {
@@ -84,7 +86,7 @@ static inline Type& StructAfter(TObject &X)
#define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \
inline void _instance_assertion_on_line_##_line (void) const \
{ \
- ASSERT_STATIC (_assertion); \
+ static_assert ((_assertion), ""); \
ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
}
# define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
@@ -129,14 +131,16 @@ static inline Type& StructAfter(TObject &X)
*/
/* Global nul-content Null pool. Enlarge as necessary. */
-/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
-static const void *_NullPool[(256+8) / sizeof (void *)];
+
+#define HB_NULL_POOL_SIZE 264
+static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
+extern HB_INTERNAL const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)];
/* Generic nul-content Null objects. */
template <typename Type>
static inline const Type& Null (void) {
- ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool));
- return *CastP<Type> (_NullPool);
+ 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. */
@@ -146,7 +150,7 @@ 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 */ \
-ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type))
+static_assert (Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.")
/* Accessor macro. */
#define Null(Type) Null<Type>()
@@ -171,16 +175,6 @@ struct hb_dispatch_context_t
* Sanitize
*/
-#ifndef HB_DEBUG_SANITIZE
-#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
-#endif
-
-
-#define TRACE_SANITIZE(this) \
- hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
- (&c->debug_depth, c->get_name (), this, HB_FUNC, \
- "");
-
/* This limits sanitizing time on really broken fonts. */
#ifndef HB_SANITIZE_MAX_EDITS
#define HB_SANITIZE_MAX_EDITS 32
@@ -191,9 +185,9 @@ struct hb_sanitize_context_t :
{
inline hb_sanitize_context_t (void) :
debug_depth (0),
- start (NULL), end (NULL),
+ start (nullptr), end (nullptr),
writable (false), edit_count (0),
- blob (NULL) {}
+ blob (nullptr) {}
inline const char *get_name (void) { return "SANITIZE"; }
template <typename T, typename F>
@@ -213,7 +207,7 @@ struct hb_sanitize_context_t :
inline void start_processing (void)
{
- this->start = hb_blob_get_data (this->blob, NULL);
+ this->start = hb_blob_get_data (this->blob, nullptr);
this->end = this->start + hb_blob_get_length (this->blob);
assert (this->start <= this->end); /* Must not overflow. */
this->edit_count = 0;
@@ -232,8 +226,8 @@ struct hb_sanitize_context_t :
this->start, this->end, this->edit_count);
hb_blob_destroy (this->blob);
- this->blob = NULL;
- this->start = this->end = NULL;
+ this->blob = nullptr;
+ this->start = this->end = nullptr;
}
inline bool check_range (const void *base, unsigned int len) const
@@ -348,7 +342,7 @@ struct Sanitizer
} else {
unsigned int edit_count = c->edit_count;
if (edit_count && !c->writable) {
- c->start = hb_blob_get_data_writable (blob, NULL);
+ c->start = hb_blob_get_data_writable (blob, nullptr);
c->end = c->start + hb_blob_get_length (blob);
if (c->start) {
@@ -373,7 +367,7 @@ struct Sanitizer
static const Type* lock_instance (hb_blob_t *blob) {
hb_blob_make_immutable (blob);
- const char *base = hb_blob_get_data (blob, NULL);
+ const char *base = hb_blob_get_data (blob, nullptr);
return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
}
};
@@ -384,16 +378,6 @@ struct Sanitizer
* Serialize
*/
-#ifndef HB_DEBUG_SERIALIZE
-#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
-#endif
-
-
-#define TRACE_SERIALIZE(this) \
- hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
- (&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
- "");
-
struct hb_serialize_context_t
{
@@ -444,7 +428,7 @@ struct hb_serialize_context_t
{
if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) {
this->ran_out_of_room = true;
- return NULL;
+ return nullptr;
}
memset (this->head, 0, size);
char *ret = this->head;
@@ -470,7 +454,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.get_size ();
Type *ret = this->allocate_size<Type> (size);
- if (unlikely (!ret)) return NULL;
+ if (unlikely (!ret)) return nullptr;
memcpy (ret, obj, size);
return ret;
}
@@ -480,7 +464,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.min_size;
assert (this->start <= (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
return reinterpret_cast<Type *> (&obj);
}
@@ -489,7 +473,7 @@ struct hb_serialize_context_t
{
unsigned int size = obj.get_size ();
assert (this->start < (char *) &obj && (char *) &obj <= this->head && (char *) &obj + size >= this->head);
- if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return NULL;
+ if (unlikely (!this->allocate_size<Type> (((char *) &obj) + size - this->head))) return nullptr;
return reinterpret_cast<Type *> (&obj);
}
@@ -631,10 +615,11 @@ struct IntType
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
- inline int cmp (Type a) const
+ template <typename Type2>
+ inline int cmp (Type2 a) const
{
Type b = v;
- if (sizeof (Type) < sizeof (int))
+ if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
return (int) a - (int) b;
else
return a < b ? -1 : a == b ? 0 : +1;
@@ -650,23 +635,22 @@ struct IntType
DEFINE_SIZE_STATIC (Size);
};
-typedef IntType<int8_t , 1> CHAR; /* 8-bit signed integer. */
-typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */
-typedef IntType<int8_t , 1> INT8; /* 8-bit signed integer. */
-typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
-typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
-typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
-typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
+typedef IntType<uint8_t, 1> UINT8; /* 8-bit unsigned integer. */
+typedef IntType<int8_t, 1> INT8; /* 8-bit signed integer. */
+typedef IntType<uint16_t, 2> UINT16; /* 16-bit unsigned integer. */
+typedef IntType<int16_t, 2> INT16; /* 16-bit signed integer. */
+typedef IntType<uint32_t, 4> UINT32; /* 32-bit unsigned integer. */
+typedef IntType<int32_t, 4> INT32; /* 32-bit signed integer. */
typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
-/* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
-typedef SHORT FWORD;
+/* 16-bit signed integer (INT16) that describes a quantity in FUnits. */
+typedef INT16 FWORD;
-/* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
-typedef USHORT UFWORD;
+/* 16-bit unsigned integer (UINT16) that describes a quantity in FUnits. */
+typedef UINT16 UFWORD;
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
-struct F2DOT14 : SHORT
+struct F2DOT14 : INT16
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@@ -675,7 +659,7 @@ struct F2DOT14 : SHORT
};
/* 32-bit signed fixed-point number (16.16). */
-struct Fixed: LONG
+struct Fixed: INT32
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@@ -693,15 +677,15 @@ struct LONGDATETIME
return_trace (likely (c->check_struct (this)));
}
protected:
- LONG major;
- ULONG minor;
+ INT32 major;
+ UINT32 minor;
public:
DEFINE_SIZE_STATIC (8);
};
/* Array of four uint8s (length = 32 bits) used to identify a script, language
* system, feature, or baseline */
-struct Tag : ULONG
+struct Tag : UINT32
{
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
@@ -712,19 +696,16 @@ struct Tag : ULONG
DEFINE_NULL_DATA (Tag, " ");
/* Glyph index number, same as uint16 (length = 16 bits) */
-struct GlyphID : USHORT {
- static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); }
- inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; }
-};
+typedef UINT16 GlyphID;
/* Script/language-system/feature index */
-struct Index : USHORT {
+struct Index : UINT16 {
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
};
DEFINE_NULL_DATA (Index, "\xff\xff");
/* Offset, Null offset = 0 */
-template <typename Type=USHORT>
+template <typename Type>
struct Offset : Type
{
inline bool is_null (void) const { return 0 == *this; }
@@ -732,15 +713,18 @@ struct Offset : Type
DEFINE_SIZE_STATIC (sizeof(Type));
};
+typedef Offset<UINT16> Offset16;
+typedef Offset<UINT32> Offset32;
+
/* CheckSum */
-struct CheckSum : ULONG
+struct CheckSum : UINT32
{
/* This is reference implementation from the spec. */
- static inline uint32_t CalcTableChecksum (const ULONG *Table, uint32_t Length)
+ static inline uint32_t CalcTableChecksum (const UINT32 *Table, uint32_t Length)
{
uint32_t Sum = 0L;
- const ULONG *EndPtr = Table+((Length+3) & ~3) / ULONG::static_size;
+ const UINT32 *EndPtr = Table+((Length+3) & ~3) / UINT32::static_size;
while (Table < EndPtr)
Sum += *Table++;
@@ -749,7 +733,7 @@ struct CheckSum : ULONG
/* Note: data should be 4byte aligned and have 4byte padding at the end. */
inline void set_for_data (const void *data, unsigned int length)
- { set (CalcTableChecksum ((const ULONG *) data, length)); }
+ { set (CalcTableChecksum ((const UINT32 *) data, length)); }
public:
DEFINE_SIZE_STATIC (4);
@@ -760,7 +744,7 @@ struct CheckSum : ULONG
* Version Numbers
*/
-template <typename FixedType=USHORT>
+template <typename FixedType=UINT16>
struct FixedVersion
{
inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
@@ -784,7 +768,7 @@ struct FixedVersion
* Use: (base+offset)
*/
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=UINT16>
struct OffsetTo : Offset<OffsetType>
{
inline const Type& operator () (const void *base) const
@@ -829,6 +813,7 @@ struct OffsetTo : Offset<OffsetType>
}
DEFINE_SIZE_STATIC (sizeof(OffsetType));
};
+template <typename Type> struct LOffsetTo : OffsetTo<Type, UINT32> {};
template <typename Base, typename OffsetType, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
template <typename Base, typename OffsetType, typename Type>
@@ -840,7 +825,7 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
*/
/* An array with a number of elements. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=UINT16>
struct ArrayOf
{
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
@@ -941,7 +926,7 @@ struct ArrayOf
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
+ return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
}
public:
@@ -950,9 +935,10 @@ struct ArrayOf
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
};
+template <typename Type> struct LArrayOf : ArrayOf<Type, UINT32> {};
/* Array of Offset's */
-template <typename Type, typename OffsetType=USHORT>
+template <typename Type, typename OffsetType=UINT16>
struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
/* Array of offsets relative to the beginning of the array itself. */
@@ -980,7 +966,7 @@ struct OffsetListOf : OffsetArrayOf<Type>
/* An array starting at second element. */
-template <typename Type, typename LenType=USHORT>
+template <typename Type, typename LenType=UINT16>
struct HeadlessArrayOf
{
inline const Type& operator [] (unsigned int i) const
@@ -1006,12 +992,6 @@ struct HeadlessArrayOf
return_trace (true);
}
- inline bool sanitize_shallow (hb_sanitize_context_t *c) const
- {
- return c->check_struct (this)
- && c->check_array (this, Type::static_size, len);
- }
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -1029,6 +1009,15 @@ struct HeadlessArrayOf
return_trace (true);
}
+ private:
+ inline bool sanitize_shallow (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (len.sanitize (c) &&
+ (!len || c->check_array (array, Type::static_size, len - 1)));
+ }
+
+ public:
LenType len;
Type array[VAR];
public:
@@ -1036,19 +1025,22 @@ struct HeadlessArrayOf
};
-/* An array with sorted elements. Supports binary searching. */
-template <typename Type, typename LenType=USHORT>
+/*
+ * An array with sorted elements. Supports binary searching.
+ */
+template <typename Type, typename LenType=UINT16>
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 *array = this->array;
int min = 0, max = (int) this->len - 1;
while (min <= max)
{
int mid = (min + max) / 2;
- int c = this->array[mid].cmp (x);
+ int c = array[mid].cmp (x);
if (c < 0)
max = mid - 1;
else if (c > 0)
@@ -1060,6 +1052,131 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
}
};
+/*
+ * Binary-search arrays
+ */
+
+struct BinSearchHeader
+{
+ inline operator uint32_t (void) const { return len; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
+ UINT16 len;
+ UINT16 searchRangeZ;
+ UINT16 entrySelectorZ;
+ UINT16 rangeShiftZ;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+template <typename Type>
+struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
+
+
+/* Lazy struct and blob loaders. */
+
+/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+template <typename T>
+struct hb_lazy_loader_t
+{
+ inline void init (hb_face_t *face_)
+ {
+ face = face_;
+ instance = nullptr;
+ }
+
+ inline void fini (void)
+ {
+ if (instance && instance != &OT::Null(T))
+ {
+ instance->fini();
+ free (instance);
+ }
+ }
+
+ inline const T* get (void) const
+ {
+ retry:
+ T *p = (T *) hb_atomic_ptr_get (&instance);
+ if (unlikely (!p))
+ {
+ p = (T *) calloc (1, sizeof (T));
+ if (unlikely (!p))
+ p = const_cast<T *> (&OT::Null(T));
+ else
+ p->init (face);
+ if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p)))
+ {
+ if (p != &OT::Null(T))
+ p->fini ();
+ goto retry;
+ }
+ }
+ return p;
+ }
+
+ inline const T* operator-> (void) const
+ {
+ return get ();
+ }
+
+ private:
+ hb_face_t *face;
+ T *instance;
+};
+
+/* Logic is shared between hb_lazy_loader_t and hb_lazy_table_loader_t */
+template <typename T>
+struct hb_lazy_table_loader_t
+{
+ inline void init (hb_face_t *face_)
+ {
+ face = face_;
+ instance = nullptr;
+ blob = nullptr;
+ }
+
+ inline void fini (void)
+ {
+ hb_blob_destroy (blob);
+ }
+
+ inline const T* get (void) const
+ {
+ retry:
+ T *p = (T *) hb_atomic_ptr_get (&instance);
+ if (unlikely (!p))
+ {
+ 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))
+ {
+ hb_blob_destroy (blob_);
+ goto retry;
+ }
+ blob = blob_;
+ }
+ return p;
+ }
+
+ inline const T* operator-> (void) const
+ {
+ return get();
+ }
+
+ private:
+ hb_face_t *face;
+ T *instance;
+ mutable hb_blob_t *blob;
+};
+
} /* namespace OT */