|
|
|
@ -62,7 +62,6 @@ |
|
|
|
|
|
|
|
|
|
/* Error. Should never happen. */ |
|
|
|
|
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR |
|
|
|
|
#pragma GCC diagnostic error "-Wc++11-narrowing" |
|
|
|
|
#pragma GCC diagnostic error "-Wcast-align" |
|
|
|
|
#pragma GCC diagnostic error "-Wcast-function-type" |
|
|
|
|
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" |
|
|
|
@ -75,6 +74,7 @@ |
|
|
|
|
#pragma GCC diagnostic error "-Wmissing-braces" |
|
|
|
|
#pragma GCC diagnostic error "-Wmissing-declarations" |
|
|
|
|
#pragma GCC diagnostic error "-Wmissing-prototypes" |
|
|
|
|
#pragma GCC diagnostic error "-Wnarrowing" |
|
|
|
|
#pragma GCC diagnostic error "-Wnested-externs" |
|
|
|
|
#pragma GCC diagnostic error "-Wold-style-definition" |
|
|
|
|
#pragma GCC diagnostic error "-Wpointer-arith" |
|
|
|
@ -245,12 +245,8 @@ extern "C" void hb_free_impl(void *ptr); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ >= 3) |
|
|
|
|
#define HB_PURE_FUNC __attribute__((pure)) |
|
|
|
|
#define HB_CONST_FUNC __attribute__((const)) |
|
|
|
|
#define HB_PRINTF_FUNC(format_idx, arg_idx) __attribute__((__format__ (__printf__, format_idx, arg_idx))) |
|
|
|
|
#else |
|
|
|
|
#define HB_PURE_FUNC |
|
|
|
|
#define HB_CONST_FUNC |
|
|
|
|
#define HB_PRINTF_FUNC(format_idx, arg_idx) |
|
|
|
|
#endif |
|
|
|
|
#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__) |
|
|
|
@ -441,181 +437,12 @@ static int HB_UNUSED _hb_errno = 0; |
|
|
|
|
#define HB_STMT_START do |
|
|
|
|
#define HB_STMT_END while (0) |
|
|
|
|
|
|
|
|
|
/* Static-assert as expression. */ |
|
|
|
|
template <unsigned int cond> class hb_assert_constant_t; |
|
|
|
|
template <> class hb_assert_constant_t<1> {}; |
|
|
|
|
#define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) |
|
|
|
|
|
|
|
|
|
/* Lets assert int types. Saves trouble down the road. */ |
|
|
|
|
static_assert ((sizeof (int8_t) == 1), ""); |
|
|
|
|
static_assert ((sizeof (uint8_t) == 1), ""); |
|
|
|
|
static_assert ((sizeof (int16_t) == 2), ""); |
|
|
|
|
static_assert ((sizeof (uint16_t) == 2), ""); |
|
|
|
|
static_assert ((sizeof (int32_t) == 4), ""); |
|
|
|
|
static_assert ((sizeof (uint32_t) == 4), ""); |
|
|
|
|
static_assert ((sizeof (int64_t) == 8), ""); |
|
|
|
|
static_assert ((sizeof (uint64_t) == 8), ""); |
|
|
|
|
static_assert ((sizeof (hb_codepoint_t) == 4), ""); |
|
|
|
|
static_assert ((sizeof (hb_position_t) == 4), ""); |
|
|
|
|
static_assert ((sizeof (hb_mask_t) == 4), ""); |
|
|
|
|
static_assert ((sizeof (hb_var_int_t) == 4), ""); |
|
|
|
|
|
|
|
|
|
#define HB_DELETE_COPY_ASSIGN(TypeName) \ |
|
|
|
|
TypeName(const TypeName&) = delete; \
|
|
|
|
|
void operator=(const TypeName&) = delete |
|
|
|
|
#define HB_DELETE_CREATE_COPY_ASSIGN(TypeName) \ |
|
|
|
|
TypeName() = delete; \
|
|
|
|
|
TypeName(const TypeName&) = delete; \
|
|
|
|
|
void operator=(const TypeName&) = delete |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Flags */ |
|
|
|
|
|
|
|
|
|
/* Enable bitwise ops on enums marked as flags_t */ |
|
|
|
|
/* To my surprise, looks like the function resolver is happy to silently cast
|
|
|
|
|
* one enum to another... So this doesn't provide the type-checking that I |
|
|
|
|
* originally had in mind... :(. |
|
|
|
|
* |
|
|
|
|
* For MSVC warnings, see: https://github.com/harfbuzz/harfbuzz/pull/163
|
|
|
|
|
*/ |
|
|
|
|
#ifdef _MSC_VER |
|
|
|
|
# pragma warning(disable:4200) |
|
|
|
|
# pragma warning(disable:4800) |
|
|
|
|
#endif |
|
|
|
|
#define HB_MARK_AS_FLAG_T(T) \ |
|
|
|
|
extern "C++" { \
|
|
|
|
|
static inline T operator | (T l, T r) { return T ((unsigned) l | (unsigned) r); } \
|
|
|
|
|
static inline T operator & (T l, T r) { return T ((unsigned) l & (unsigned) r); } \
|
|
|
|
|
static inline T operator ^ (T l, T r) { return T ((unsigned) l ^ (unsigned) r); } \
|
|
|
|
|
static inline T operator ~ (T r) { return T (~(unsigned int) r); } \
|
|
|
|
|
static inline T& operator |= (T &l, T r) { l = l | r; return l; } \
|
|
|
|
|
static inline T& operator &= (T& l, T r) { l = l & r; return l; } \
|
|
|
|
|
static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \
|
|
|
|
|
} \
|
|
|
|
|
static_assert (true, "") |
|
|
|
|
|
|
|
|
|
/* Useful for set-operations on small enums.
|
|
|
|
|
* For example, for testing "x ∈ {x1, x2, x3}" use: |
|
|
|
|
* (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) |
|
|
|
|
*/ |
|
|
|
|
#define FLAG(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 32) + (((uint32_t) 1U) << (unsigned)(x))) |
|
|
|
|
#define FLAG_UNSAFE(x) ((unsigned)(x) < 32 ? (((uint32_t) 1U) << (unsigned)(x)) : 0) |
|
|
|
|
#define FLAG_RANGE(x,y) (ASSERT_STATIC_EXPR_ZERO ((x) < (y)) + FLAG(y+1) - FLAG(x)) |
|
|
|
|
#define FLAG64(x) (ASSERT_STATIC_EXPR_ZERO ((unsigned)(x) < 64) + (((uint64_t) 1ULL) << (unsigned)(x))) |
|
|
|
|
#define FLAG64_UNSAFE(x) ((unsigned)(x) < 64 ? (((uint64_t) 1ULL) << (unsigned)(x)) : 0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Size signifying variable-sized array */ |
|
|
|
|
#ifndef HB_VAR_ARRAY |
|
|
|
|
#define HB_VAR_ARRAY 1 |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
static inline float |
|
|
|
|
_hb_roundf (float x) { return floorf (x + .5f); } |
|
|
|
|
#define roundf(x) _hb_roundf(x) |
|
|
|
|
|
|
|
|
|
/* Endian swap, used in Windows related backends */ |
|
|
|
|
static inline uint16_t hb_uint16_swap (const uint16_t v) |
|
|
|
|
{ return (v >> 8) | (v << 8); } |
|
|
|
|
static inline uint32_t hb_uint32_swap (const uint32_t v) |
|
|
|
|
{ return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); } |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Big-endian integers. Here because fundamental. |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
template <typename Type, int Bytes> struct BEInt; |
|
|
|
|
|
|
|
|
|
template <typename Type> |
|
|
|
|
struct BEInt<Type, 1> |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
BEInt<Type, 1>& operator = (Type V) |
|
|
|
|
{ |
|
|
|
|
v = V; |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
operator Type () const { return v; } |
|
|
|
|
private: uint8_t v; |
|
|
|
|
}; |
|
|
|
|
template <typename Type> |
|
|
|
|
struct BEInt<Type, 2> |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
BEInt<Type, 2>& operator = (Type V) |
|
|
|
|
{ |
|
|
|
|
v[0] = (V >> 8) & 0xFF; |
|
|
|
|
v[1] = (V ) & 0xFF; |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
operator Type () const |
|
|
|
|
{ |
|
|
|
|
#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ |
|
|
|
|
defined(__BYTE_ORDER) && \
|
|
|
|
|
(__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) |
|
|
|
|
/* Spoon-feed the compiler a big-endian integer with alignment 1.
|
|
|
|
|
* https://github.com/harfbuzz/harfbuzz/pull/1398 */
|
|
|
|
|
struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; |
|
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN |
|
|
|
|
return __builtin_bswap16 (((packed_uint16_t *) this)->v); |
|
|
|
|
#else /* __BYTE_ORDER == __BIG_ENDIAN */ |
|
|
|
|
return ((packed_uint16_t *) this)->v; |
|
|
|
|
#endif |
|
|
|
|
#endif |
|
|
|
|
return (v[0] << 8) |
|
|
|
|
+ (v[1] ); |
|
|
|
|
} |
|
|
|
|
private: uint8_t v[2]; |
|
|
|
|
}; |
|
|
|
|
template <typename Type> |
|
|
|
|
struct BEInt<Type, 3> |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
BEInt<Type, 3>& operator = (Type V) |
|
|
|
|
{ |
|
|
|
|
v[0] = (V >> 16) & 0xFF; |
|
|
|
|
v[1] = (V >> 8) & 0xFF; |
|
|
|
|
v[2] = (V ) & 0xFF; |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
operator Type () const |
|
|
|
|
{ |
|
|
|
|
return (v[0] << 16) |
|
|
|
|
+ (v[1] << 8) |
|
|
|
|
+ (v[2] ); |
|
|
|
|
} |
|
|
|
|
private: uint8_t v[3]; |
|
|
|
|
}; |
|
|
|
|
template <typename Type> |
|
|
|
|
struct BEInt<Type, 4> |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
|
BEInt<Type, 4>& operator = (Type V) |
|
|
|
|
{ |
|
|
|
|
v[0] = (V >> 24) & 0xFF; |
|
|
|
|
v[1] = (V >> 16) & 0xFF; |
|
|
|
|
v[2] = (V >> 8) & 0xFF; |
|
|
|
|
v[3] = (V ) & 0xFF; |
|
|
|
|
return *this; |
|
|
|
|
} |
|
|
|
|
operator Type () const |
|
|
|
|
{ |
|
|
|
|
return (v[0] << 24) |
|
|
|
|
+ (v[1] << 16) |
|
|
|
|
+ (v[2] << 8) |
|
|
|
|
+ (v[3] ); |
|
|
|
|
} |
|
|
|
|
private: uint8_t v[4]; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* For lack of a better place, put Zawgyi script hack here. |
|
|
|
|
* https://github.com/harfbuzz/harfbuzz/issues/1162
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g')) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Headers we include for everyone. Keep topologically sorted by dependency.
|
|
|
|
|
* They express dependency amongst themselves, but no other file should include |
|
|
|
|