[lazy] Port more
This commit is contained in:
parent
7bd508a0c4
commit
747d2564e6
|
@ -698,7 +698,6 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
inline Returned * get_unconst (void) const { return const_cast<Returned *> (Funcs::convert (get_stored ())); }
|
inline Returned * get_unconst (void) const { return const_cast<Returned *> (Funcs::convert (get_stored ())); }
|
||||||
|
|
||||||
/* To be possibly overloaded by subclasses. */
|
/* To be possibly overloaded by subclasses. */
|
||||||
static inline const Returned* convert (const Stored *p) { return p; }
|
|
||||||
static inline Returned* convert (Stored *p) { return p; }
|
static inline Returned* convert (Stored *p) { return p; }
|
||||||
|
|
||||||
/* By default null/init/fini the object. */
|
/* By default null/init/fini the object. */
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
|
|
||||||
#include "hb-private.hh"
|
#include "hb-private.hh"
|
||||||
#include "hb-shaper-private.hh"
|
#include "hb-shaper-private.hh"
|
||||||
#include "hb-atomic-private.hh"
|
#include "hb-machinery-private.hh"
|
||||||
|
|
||||||
|
|
||||||
static const hb_shaper_pair_t all_shapers[] = {
|
static const hb_shaper_pair_t all_shapers[] = {
|
||||||
|
@ -36,52 +36,28 @@ static const hb_shaper_pair_t all_shapers[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Thread-safe, lock-free, shapers */
|
static void free_static_shapers (void);
|
||||||
|
|
||||||
static hb_atomic_ptr_t<const hb_shaper_pair_t> static_shapers;
|
static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<const hb_shaper_pair_t,
|
||||||
|
hb_shapers_lazy_loader_t>
|
||||||
#ifdef HB_USE_ATEXIT
|
|
||||||
static
|
|
||||||
void free_static_shapers (void)
|
|
||||||
{
|
{
|
||||||
retry:
|
static inline hb_shaper_pair_t *create (void)
|
||||||
const hb_shaper_pair_t *shapers = static_shapers.get ();
|
|
||||||
if (unlikely (!static_shapers.cmpexch (shapers, nullptr)))
|
|
||||||
goto retry;
|
|
||||||
|
|
||||||
if (unlikely (shapers != all_shapers))
|
|
||||||
free ((void *) shapers);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const hb_shaper_pair_t *
|
|
||||||
_hb_shapers_get (void)
|
|
||||||
{
|
|
||||||
retry:
|
|
||||||
hb_shaper_pair_t *shapers = const_cast<hb_shaper_pair_t *> (static_shapers.get ());
|
|
||||||
|
|
||||||
if (unlikely (!shapers))
|
|
||||||
{
|
{
|
||||||
char *env = getenv ("HB_SHAPER_LIST");
|
char *env = getenv ("HB_SHAPER_LIST");
|
||||||
if (!env || !*env) {
|
if (!env || !*env)
|
||||||
(void) static_shapers.cmpexch (nullptr, &all_shapers[0]);
|
return nullptr;
|
||||||
return (const hb_shaper_pair_t *) all_shapers;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Not found; allocate one. */
|
hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
|
||||||
shapers = (hb_shaper_pair_t *) calloc (1, sizeof (all_shapers));
|
|
||||||
if (unlikely (!shapers))
|
if (unlikely (!shapers))
|
||||||
{
|
return nullptr;
|
||||||
(void) static_shapers.cmpexch (nullptr, &all_shapers[0]);
|
|
||||||
return (const hb_shaper_pair_t *) all_shapers;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy (shapers, all_shapers, sizeof (all_shapers));
|
memcpy (shapers, all_shapers, sizeof (all_shapers));
|
||||||
|
|
||||||
/* Reorder shaper list to prefer requested shapers. */
|
/* Reorder shaper list to prefer requested shapers. */
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
char *end, *p = env;
|
char *end, *p = env;
|
||||||
for (;;) {
|
for (;;)
|
||||||
|
{
|
||||||
end = strchr (p, ',');
|
end = strchr (p, ',');
|
||||||
if (!end)
|
if (!end)
|
||||||
end = p + strlen (p);
|
end = p + strlen (p);
|
||||||
|
@ -103,16 +79,32 @@ retry:
|
||||||
p = end + 1;
|
p = end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (!static_shapers.cmpexch (nullptr, shapers)))
|
|
||||||
{
|
|
||||||
free (shapers);
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HB_USE_ATEXIT
|
#ifdef HB_USE_ATEXIT
|
||||||
atexit (free_static_shapers); /* First person registers atexit() callback. */
|
atexit (free_static_shapers);
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
return shapers;
|
return shapers;
|
||||||
}
|
}
|
||||||
|
static inline void destroy (const hb_shaper_pair_t *p)
|
||||||
|
{
|
||||||
|
free ((void *) p);
|
||||||
|
}
|
||||||
|
static inline const hb_shaper_pair_t *get_null (void)
|
||||||
|
{
|
||||||
|
return all_shapers;
|
||||||
|
}
|
||||||
|
} static_shapers;
|
||||||
|
|
||||||
|
#ifdef HB_USE_ATEXIT
|
||||||
|
static
|
||||||
|
void free_static_shapers (void)
|
||||||
|
{
|
||||||
|
static_shapers.free_instance ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const hb_shaper_pair_t *
|
||||||
|
_hb_shapers_get (void)
|
||||||
|
{
|
||||||
|
return static_shapers.get_unconst ();
|
||||||
|
}
|
||||||
|
|
|
@ -190,7 +190,8 @@ hb_ScriptPlaceOpenType(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct hb_uniscribe_shaper_funcs_t {
|
struct hb_uniscribe_shaper_funcs_t
|
||||||
|
{
|
||||||
SIOT ScriptItemizeOpenType;
|
SIOT ScriptItemizeOpenType;
|
||||||
SSOT ScriptShapeOpenType;
|
SSOT ScriptShapeOpenType;
|
||||||
SPOT ScriptPlaceOpenType;
|
SPOT ScriptPlaceOpenType;
|
||||||
|
|
Loading…
Reference in New Issue