diff options
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-machinery.hh')
-rw-r--r-- | src/3rdparty/harfbuzz-ng/src/hb-machinery.hh | 113 |
1 files changed, 61 insertions, 52 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh index 15535d75bd..ecff94f1b6 100644 --- a/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh +++ b/src/3rdparty/harfbuzz-ng/src/hb-machinery.hh @@ -34,29 +34,12 @@ #include "hb-dispatch.hh" #include "hb-sanitize.hh" -#include "hb-serialize.hh" /* * Casts */ -/* Cast to struct T, reference to reference */ -template<typename Type, typename TObject> -static inline const Type& CastR(const TObject &X) -{ return reinterpret_cast<const Type&> (X); } -template<typename Type, typename TObject> -static inline Type& CastR(TObject &X) -{ return reinterpret_cast<Type&> (X); } - -/* Cast to struct T, pointer to pointer */ -template<typename Type, typename TObject> -static inline const Type* CastP(const TObject *X) -{ return reinterpret_cast<const Type*> (X); } -template<typename Type, typename TObject> -static inline Type* CastP(TObject *X) -{ return reinterpret_cast<Type*> (X); } - /* StructAtOffset<T>(P,Ofs) returns the struct T& that is placed at memory * location pointed to by P plus Ofs bytes. */ template<typename Type> @@ -70,7 +53,7 @@ static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int of { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" - return * reinterpret_cast<Type*> ((char *) P + offset); + return * reinterpret_cast<const Type*> ((const char *) P + offset); #pragma GCC diagnostic pop } template<typename Type> @@ -96,6 +79,11 @@ static inline Type& StructAfter(TObject &X) * Size checking */ +/* Size signifying variable-sized array */ +#ifndef HB_VAR_ARRAY +#define HB_VAR_ARRAY 1 +#endif + /* Check _assertion in a method environment */ #define _DEFINE_INSTANCE_ASSERTION1(_line, _assertion) \ void _instance_assertion_on_line_##_line () const \ @@ -135,7 +123,7 @@ static inline Type& StructAfter(TObject &X) #define DEFINE_SIZE_ARRAY(size, array) \ DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \ - DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + HB_VAR_ARRAY * sizeof ((array)[0])) \ + DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + (HB_VAR_ARRAY+0) * sizeof ((array)[0])) \ static constexpr unsigned null_size = (size); \ static constexpr unsigned min_size = (size) @@ -147,6 +135,13 @@ static inline Type& StructAfter(TObject &X) /* * Lazy loaders. + * + * The lazy-loaders are thread-safe pointer-like objects that create their + * instead on-demand. They also support access to a "data" object that is + * necessary for creating their instance. The data object, if specified, + * is accessed via pointer math, located at a location before the position + * of the loader itself. This avoids having to store a pointer to data + * for every lazy-loader. Multiple lazy-loaders can access the same data. */ template <typename Data, unsigned int WheresData> @@ -185,14 +180,17 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored> >::value Funcs; + hb_lazy_loader_t () = default; + hb_lazy_loader_t (const hb_lazy_loader_t &other) = delete; + void init0 () {} /* Init, when memory is already set to 0. No-op for us. */ void init () { instance.set_relaxed (nullptr); } - void fini () { do_destroy (instance.get ()); } + void fini () { do_destroy (instance.get_acquire ()); init (); } void free_instance () { retry: - Stored *p = instance.get (); + Stored *p = instance.get_acquire (); if (unlikely (p && !cmpexch (p, nullptr))) goto retry; do_destroy (p); @@ -205,7 +203,8 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> } const Returned * operator -> () const { return get (); } - const Returned & operator * () const { return *get (); } + template <typename U = Returned, hb_enable_if (!hb_is_same (U, void))> + const U & operator * () const { return *get (); } explicit operator bool () const { return get_stored () != Funcs::get_null (); } template <typename C> operator const C * () const { return get (); } @@ -213,7 +212,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> Stored * get_stored () const { retry: - Stored *p = this->instance.get (); + Stored *p = this->instance.get_acquire (); if (unlikely (!p)) { if (unlikely (this->is_inert ())) @@ -238,7 +237,8 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> bool cmpexch (Stored *current, Stored *value) const { - /* This *must* be called when there are no other threads accessing. */ + /* This function can only be safely called directly if no + * other thread is accessing. */ return this->instance.cmpexch (current, value); } @@ -250,28 +250,28 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> static Returned* convert (Stored *p) { return p; } /* By default null/init/fini the object. */ - static const Stored* get_null () { return &Null(Stored); } + static const Stored* get_null () { return &Null (Stored); } static Stored *create (Data *data) { - Stored *p = (Stored *) calloc (1, sizeof (Stored)); + Stored *p = (Stored *) hb_calloc (1, sizeof (Stored)); if (likely (p)) - p->init (data); + p = new (p) Stored (data); return p; } static Stored *create () { - Stored *p = (Stored *) calloc (1, sizeof (Stored)); + Stored *p = (Stored *) hb_calloc (1, sizeof (Stored)); if (likely (p)) - p->init (); + p = new (p) Stored (); return p; } static void destroy (Stored *p) { - p->fini (); - free (p); + p->~Stored (); + hb_free (p); } -// private: + private: /* Must only have one pointer. */ hb_atomic_ptr_t<Stored *> instance; }; @@ -281,16 +281,25 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData> template <typename T, unsigned int WheresFace> struct hb_face_lazy_loader_t : hb_lazy_loader_t<T, hb_face_lazy_loader_t<T, WheresFace>, - hb_face_t, WheresFace> {}; + hb_face_t, WheresFace> +{ + // Hack; have them here for API parity with hb_table_lazy_loader_t + hb_blob_t *get_blob () { return this->get ()->get_blob (); } +}; -template <typename T, unsigned int WheresFace> +template <typename T, unsigned int WheresFace, bool core=false> struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, - hb_table_lazy_loader_t<T, WheresFace>, + hb_table_lazy_loader_t<T, WheresFace, core>, hb_face_t, WheresFace, hb_blob_t> { static hb_blob_t *create (hb_face_t *face) - { return hb_sanitize_context_t ().reference_table<T> (face); } + { + hb_sanitize_context_t c; + if (core) + c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs + return c.reference_table<T> (face); + } static void destroy (hb_blob_t *p) { hb_blob_destroy (p); } static const hb_blob_t *get_null () @@ -302,22 +311,22 @@ struct hb_table_lazy_loader_t : hb_lazy_loader_t<T, hb_blob_t* get_blob () const { return this->get_stored (); } }; -template <typename Subclass> -struct hb_font_funcs_lazy_loader_t : hb_lazy_loader_t<hb_font_funcs_t, Subclass> -{ - static void destroy (hb_font_funcs_t *p) - { hb_font_funcs_destroy (p); } - static const hb_font_funcs_t *get_null () - { return hb_font_funcs_get_empty (); } -}; -template <typename Subclass> -struct hb_unicode_funcs_lazy_loader_t : hb_lazy_loader_t<hb_unicode_funcs_t, Subclass> -{ - static void destroy (hb_unicode_funcs_t *p) - { hb_unicode_funcs_destroy (p); } - static const hb_unicode_funcs_t *get_null () - { return hb_unicode_funcs_get_empty (); } -}; +#define HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T(Type) \ + template <typename Subclass> \ + struct hb_##Type##_funcs_lazy_loader_t : hb_lazy_loader_t<hb_##Type##_funcs_t, Subclass> \ + { \ + static void destroy (hb_##Type##_funcs_t *p) \ + { hb_##Type##_funcs_destroy (p); } \ + static const hb_##Type##_funcs_t *get_null () \ + { return hb_##Type##_funcs_get_empty (); } \ + } + +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (font); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (unicode); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (draw); +HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T (paint); + +#undef HB_DEFINE_TYPE_FUNCS_LAZY_LOADER_T #endif /* HB_MACHINERY_HH */ |