< prev index next >

src/java.desktop/share/native/libfontmanager/harfbuzz/hb-open-type-private.hh

Print this page

        

*** 28,37 **** --- 28,39 ---- #ifndef HB_OPEN_TYPE_PRIVATE_HH #define HB_OPEN_TYPE_PRIVATE_HH #include "hb-private.hh" + #include "hb-debug.hh" + #include "hb-face-private.hh" namespace OT {
*** 82,92 **** /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ inline void _instance_assertion_on_line_##_line (void) const \ { \ ! ASSERT_STATIC (_assertion); \ ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \ } # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion) --- 84,94 ---- /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ inline void _instance_assertion_on_line_##_line (void) const \ { \ ! static_assert ((_assertion), ""); \ ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \ } # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion) # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
*** 127,154 **** /* * Null objects */ /* 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 *)]; /* Generic nul-content Null objects. */ template <typename Type> static inline const Type& Null (void) { ! ASSERT_STATIC (sizeof (Type) <= sizeof (_NullPool)); ! return *CastP<Type> (_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 */ \ ! ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) /* Accessor macro. */ #define Null(Type) Null<Type>() --- 129,158 ---- /* * 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."); ! 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) { ! 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>()
*** 169,201 **** /* * 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 #endif struct hb_sanitize_context_t : hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> { inline hb_sanitize_context_t (void) : debug_depth (0), ! start (NULL), end (NULL), writable (false), edit_count (0), ! blob (NULL) {} inline const char *get_name (void) { return "SANITIZE"; } template <typename T, typename F> inline bool may_dispatch (const T *obj, const F *format) { return format->sanitize (this); } --- 173,195 ---- /* * Sanitize */ /* This limits sanitizing time on really broken fonts. */ #ifndef HB_SANITIZE_MAX_EDITS #define HB_SANITIZE_MAX_EDITS 32 #endif struct hb_sanitize_context_t : hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> { inline hb_sanitize_context_t (void) : debug_depth (0), ! start (nullptr), end (nullptr), writable (false), edit_count (0), ! blob (nullptr) {} inline const char *get_name (void) { return "SANITIZE"; } template <typename T, typename F> inline bool may_dispatch (const T *obj, const F *format) { return format->sanitize (this); }
*** 211,221 **** this->writable = false; } inline void start_processing (void) { ! this->start = hb_blob_get_data (this->blob, NULL); this->end = this->start + hb_blob_get_length (this->blob); assert (this->start <= this->end); /* Must not overflow. */ this->edit_count = 0; this->debug_depth = 0; --- 205,215 ---- this->writable = false; } inline void start_processing (void) { ! 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; this->debug_depth = 0;
*** 230,241 **** DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, "end [%p..%p] %u edit requests", this->start, this->end, this->edit_count); hb_blob_destroy (this->blob); ! this->blob = NULL; ! this->start = this->end = NULL; } inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base; --- 224,235 ---- DEBUG_MSG_LEVEL (SANITIZE, this->start, 0, -1, "end [%p..%p] %u edit requests", this->start, this->end, this->edit_count); hb_blob_destroy (this->blob); ! this->blob = nullptr; ! this->start = this->end = nullptr; } inline bool check_range (const void *base, unsigned int len) const { const char *p = (const char *) base;
*** 346,356 **** } } } else { unsigned int edit_count = c->edit_count; if (edit_count && !c->writable) { ! c->start = hb_blob_get_data_writable (blob, NULL); c->end = c->start + hb_blob_get_length (blob); if (c->start) { c->writable = true; /* ok, we made it writable by relocating. try again */ --- 340,350 ---- } } } else { 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); if (c->start) { c->writable = true; /* ok, we made it writable by relocating. try again */
*** 371,401 **** } } static const Type* lock_instance (hb_blob_t *blob) { hb_blob_make_immutable (blob); ! const char *base = hb_blob_get_data (blob, NULL); return unlikely (!base) ? &Null(Type) : CastP<Type> (base); } }; /* * 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 { inline hb_serialize_context_t (void *start_, unsigned int size) { --- 365,385 ---- } } 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); } }; /* * Serialize */ struct hb_serialize_context_t { inline hb_serialize_context_t (void *start_, unsigned int size) {
*** 442,452 **** template <typename Type> inline Type *allocate_size (unsigned int size) { if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) { this->ran_out_of_room = true; ! return NULL; } memset (this->head, 0, size); char *ret = this->head; this->head += size; return reinterpret_cast<Type *> (ret); --- 426,436 ---- template <typename Type> inline Type *allocate_size (unsigned int size) { if (unlikely (this->ran_out_of_room || this->end - this->head < ptrdiff_t (size))) { this->ran_out_of_room = true; ! return nullptr; } memset (this->head, 0, size); char *ret = this->head; this->head += size; return reinterpret_cast<Type *> (ret);
*** 468,497 **** template <typename Type> inline Type *embed (const Type &obj) { unsigned int size = obj.get_size (); Type *ret = this->allocate_size<Type> (size); ! if (unlikely (!ret)) return NULL; memcpy (ret, obj, size); return ret; } template <typename Type> inline Type *extend_min (Type &obj) { 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; return reinterpret_cast<Type *> (&obj); } template <typename Type> inline Type *extend (Type &obj) { 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; return reinterpret_cast<Type *> (&obj); } inline void truncate (void *new_head) { --- 452,481 ---- template <typename Type> inline Type *embed (const Type &obj) { unsigned int size = obj.get_size (); Type *ret = this->allocate_size<Type> (size); ! if (unlikely (!ret)) return nullptr; memcpy (ret, obj, size); return ret; } template <typename Type> inline Type *extend_min (Type &obj) { 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 nullptr; return reinterpret_cast<Type *> (&obj); } template <typename Type> inline Type *extend (Type &obj) { 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 nullptr; return reinterpret_cast<Type *> (&obj); } inline void truncate (void *new_head) {
*** 629,642 **** inline void set (Type i) { v.set (i); } inline operator Type(void) const { return v; } 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 { Type b = v; ! if (sizeof (Type) < sizeof (int)) return (int) a - (int) b; else return a < b ? -1 : a == b ? 0 : +1; } inline bool sanitize (hb_sanitize_context_t *c) const --- 613,627 ---- inline void set (Type i) { v.set (i); } inline operator Type(void) const { return v; } 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); } ! template <typename Type2> ! inline int cmp (Type2 a) const { Type b = v; ! if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int)) return (int) a - (int) b; else return a < b ? -1 : a == b ? 0 : +1; } inline bool sanitize (hb_sanitize_context_t *c) const
*** 648,660 **** BEInt<Type, Size> v; public: 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<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ --- 633,645 ---- BEInt<Type, Size> v; public: 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<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
*** 710,723 **** DEFINE_SIZE_STATIC (4); }; 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; } ! }; /* Script/language-system/feature index */ struct Index : USHORT { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; }; --- 695,705 ---- DEFINE_SIZE_STATIC (4); }; DEFINE_NULL_DATA (Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ ! typedef USHORT GlyphID; /* Script/language-system/feature index */ struct Index : USHORT { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; };
*** 827,836 **** --- 809,819 ---- inline bool neuter (hb_sanitize_context_t *c) const { return c->try_set (this, 0); } DEFINE_SIZE_STATIC (sizeof(OffsetType)); }; + template <typename Type> struct LOffsetTo : OffsetTo<Type, ULONG> {}; 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> static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
*** 939,957 **** private: 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)); } public: LenType len; Type array[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; /* Array of Offset's */ template <typename Type, typename OffsetType=USHORT> struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {}; --- 922,941 ---- 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)); } public: LenType len; Type array[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; + template <typename Type> struct LArrayOf : ArrayOf<Type, ULONG> {}; /* Array of Offset's */ template <typename Type, typename OffsetType=USHORT> struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
*** 1004,1019 **** array[i] = items[i]; items.advance (items_len - 1); 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); if (unlikely (!sanitize_shallow (c))) return_trace (false); --- 988,997 ----
*** 1027,1056 **** (void) (false && array[0].sanitize (c)); return_trace (true); } LenType len; Type array[VAR]; public: DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; ! /* An array with sorted elements. Supports binary searching. */ template <typename Type, typename LenType=USHORT> 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. */ int min = 0, max = (int) this->len - 1; while (min <= max) { int mid = (min + max) / 2; ! int c = this->array[mid].cmp (x); if (c < 0) max = mid - 1; else if (c > 0) min = mid + 1; else --- 1005,1046 ---- (void) (false && array[0].sanitize (c)); 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: DEFINE_SIZE_ARRAY (sizeof (LenType), array); }; ! /* ! * An array with sorted elements. Supports binary searching. ! */ template <typename Type, typename LenType=USHORT> 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 = array[mid].cmp (x); if (c < 0) max = mid - 1; else if (c > 0) min = mid + 1; else
*** 1058,1067 **** --- 1048,1182 ---- } return -1; } }; + /* + * 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: + USHORT len; + USHORT searchRangeZ; + USHORT entrySelectorZ; + USHORT 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 */ #endif /* HB_OPEN_TYPE_PRIVATE_HH */
< prev index next >