< prev index next >
src/java.desktop/share/native/libfontmanager/harfbuzz/hb-common.cc
Print this page
*** 24,60 ****
*
* Red Hat Author(s): Behdad Esfahbod
* Google Author(s): Behdad Esfahbod
*/
! #include "hb-private.hh"
! #include "hb-mutex-private.hh"
! #include "hb-object-private.hh"
#include <locale.h>
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
/* hb_options_t */
! hb_options_union_t _hb_options;
void
! _hb_options_init (void)
{
hb_options_union_t u;
u.i = 0;
! u.opts.initialized = 1;
! char *c = getenv ("HB_OPTIONS");
! u.opts.uniscribe_bug_compatible = c && strstr (c, "uniscribe-bug-compatible");
/* This is idempotent and threadsafe. */
! _hb_options = u;
}
/* hb_tag_t */
--- 24,88 ----
*
* Red Hat Author(s): Behdad Esfahbod
* Google Author(s): Behdad Esfahbod
*/
! #include "hb.hh"
! #include "hb-machinery.hh"
#include <locale.h>
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
+ /**
+ * SECTION:hb-common
+ * @title: hb-common
+ * @short_description: Common data types
+ * @include: hb.h
+ *
+ * Common data types used across HarfBuzz are defined here.
+ **/
+
+
/* hb_options_t */
! hb_atomic_int_t _hb_options;
void
! _hb_options_init ()
{
hb_options_union_t u;
u.i = 0;
! u.opts.initialized = true;
! const char *c = getenv ("HB_OPTIONS");
! if (c)
! {
! while (*c)
! {
! const char *p = strchr (c, ':');
! if (!p)
! p = c + strlen (c);
!
! #define OPTION(name, symbol) \
! if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
!
! OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
! OPTION ("aat", aat);
!
! #undef OPTION
!
! c = *p ? p + 1 : p;
! }
!
! }
/* This is idempotent and threadsafe. */
! _hb_options.set_relaxed (u.i);
}
/* hb_tag_t */
*** 174,184 ****
static const char canon_map[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
! '-', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
};
--- 202,212 ----
static const char canon_map[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '-', 0, 0,
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 0, 0, 0, 0, 0, 0,
! 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, '-',
0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 0, 0, 0, 0, 0
};
*** 217,231 ****
struct hb_language_item_t {
struct hb_language_item_t *next;
hb_language_t lang;
! inline bool operator == (const char *s) const {
! return lang_equal (lang, s);
! }
! inline hb_language_item_t & operator = (const char *s) {
/* If a custom allocated is used calling strdup() pairs
badly with a call to the custom free() in fini() below.
Therefore don't call strdup(), implement its behavior.
*/
size_t len = strlen(s) + 1;
--- 245,258 ----
struct hb_language_item_t {
struct hb_language_item_t *next;
hb_language_t lang;
! bool operator == (const char *s) const
! { return lang_equal (lang, s); }
! hb_language_item_t & operator = (const char *s) {
/* If a custom allocated is used calling strdup() pairs
badly with a call to the custom free() in fini() below.
Therefore don't call strdup(), implement its behavior.
*/
size_t len = strlen(s) + 1;
*** 238,262 ****
}
return *this;
}
! void fini (void) { free ((void *) lang); }
};
/* Thread-safe lock-free language list */
! static hb_language_item_t *langs;
! #ifdef HB_USE_ATEXIT
static void
! free_langs (void)
{
retry:
! hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
! if (!hb_atomic_ptr_cmpexch (&langs, first_lang, nullptr))
goto retry;
while (first_lang) {
hb_language_item_t *next = first_lang->next;
first_lang->fini ();
--- 265,289 ----
}
return *this;
}
! void fini () { free ((void *) lang); }
};
/* Thread-safe lock-free language list */
! static hb_atomic_ptr_t <hb_language_item_t> langs;
! #if HB_USE_ATEXIT
static void
! free_langs ()
{
retry:
! hb_language_item_t *first_lang = langs;
! if (unlikely (!langs.cmpexch (first_lang, nullptr)))
goto retry;
while (first_lang) {
hb_language_item_t *next = first_lang->next;
first_lang->fini ();
*** 268,278 ****
static hb_language_item_t *
lang_find_or_insert (const char *key)
{
retry:
! hb_language_item_t *first_lang = (hb_language_item_t *) hb_atomic_ptr_get (&langs);
for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
if (*lang == key)
return lang;
--- 295,305 ----
static hb_language_item_t *
lang_find_or_insert (const char *key)
{
retry:
! hb_language_item_t *first_lang = langs;
for (hb_language_item_t *lang = first_lang; lang; lang = lang->next)
if (*lang == key)
return lang;
*** 286,302 ****
{
free (lang);
return nullptr;
}
! if (!hb_atomic_ptr_cmpexch (&langs, first_lang, lang)) {
lang->fini ();
free (lang);
goto retry;
}
! #ifdef HB_USE_ATEXIT
if (!first_lang)
atexit (free_langs); /* First person registers atexit() callback. */
#endif
return lang;
--- 313,330 ----
{
free (lang);
return nullptr;
}
! if (unlikely (!langs.cmpexch (first_lang, lang)))
! {
lang->fini ();
free (lang);
goto retry;
}
! #if HB_USE_ATEXIT
if (!first_lang)
atexit (free_langs); /* First person registers atexit() callback. */
#endif
return lang;
*** 304,321 ****
/**
* hb_language_from_string:
* @str: (array length=len) (element-type uint8_t): a string representing
! * ISO 639 language code
* @len: length of the @str, or -1 if it is %NULL-terminated.
*
! * Converts @str representing an ISO 639 language code to the corresponding
* #hb_language_t.
*
* Return value: (transfer none):
! * The #hb_language_t corresponding to the ISO 639 language code.
*
* Since: 0.9.2
**/
hb_language_t
hb_language_from_string (const char *str, int len)
--- 332,349 ----
/**
* hb_language_from_string:
* @str: (array length=len) (element-type uint8_t): a string representing
! * a BCP 47 language tag
* @len: length of the @str, or -1 if it is %NULL-terminated.
*
! * Converts @str representing a BCP 47 language tag to the corresponding
* #hb_language_t.
*
* Return value: (transfer none):
! * The #hb_language_t corresponding to the BCP 47 language tag.
*
* Since: 0.9.2
**/
hb_language_t
hb_language_from_string (const char *str, int len)
*** 359,386 ****
}
/**
* hb_language_get_default:
*
*
*
* Return value: (transfer none):
*
* Since: 0.9.2
**/
hb_language_t
! hb_language_get_default (void)
{
! static hb_language_t default_language = HB_LANGUAGE_INVALID;
! hb_language_t language = (hb_language_t) hb_atomic_ptr_get (&default_language);
! if (unlikely (language == HB_LANGUAGE_INVALID)) {
language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
! (void) hb_atomic_ptr_cmpexch (&default_language, HB_LANGUAGE_INVALID, language);
}
! return default_language;
}
/* hb_script_t */
--- 387,422 ----
}
/**
* hb_language_get_default:
*
+ * Get default language from current locale.
*
+ * Note that the first time this function is called, it calls
+ * "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying
+ * setlocale function is, in many implementations, NOT threadsafe. To avoid
+ * problems, call this function once before multiple threads can call it.
+ * This function is only used from hb_buffer_guess_segment_properties() by
+ * HarfBuzz itself.
*
* Return value: (transfer none):
*
* Since: 0.9.2
**/
hb_language_t
! hb_language_get_default ()
{
! static hb_atomic_ptr_t <hb_language_t> default_language;
! hb_language_t language = default_language;
! if (unlikely (language == HB_LANGUAGE_INVALID))
! {
language = hb_language_from_string (setlocale (LC_CTYPE, nullptr), -1);
! (void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
}
! return language;
}
/* hb_script_t */
*** 528,538 ****
case HB_SCRIPT_PALMYRENE:
case HB_SCRIPT_PSALTER_PAHLAVI:
/* Unicode-8.0 additions */
case HB_SCRIPT_HATRAN:
- case HB_SCRIPT_OLD_HUNGARIAN:
/* Unicode-9.0 additions */
case HB_SCRIPT_ADLAM:
/* Unicode-11.0 additions */
--- 564,573 ----
*** 542,552 ****
--- 577,589 ----
return HB_DIRECTION_RTL;
/* https://github.com/harfbuzz/harfbuzz/issues/1000 */
+ case HB_SCRIPT_OLD_HUNGARIAN:
case HB_SCRIPT_OLD_ITALIC:
+ case HB_SCRIPT_RUNIC:
return HB_DIRECTION_INVALID;
}
return HB_DIRECTION_LTR;
*** 585,594 ****
--- 622,644 ----
}
/* hb_version */
+
+ /**
+ * SECTION:hb-version
+ * @title: hb-version
+ * @short_description: Information about the version of HarfBuzz in use
+ * @include: hb.h
+ *
+ * These functions and macros allow accessing version of the HarfBuzz
+ * library used at compile- as well as run-time, and to direct code
+ * conditionally based on those versions, again, at compile- or run-time.
+ **/
+
+
/**
* hb_version:
* @major: (out): Library major version component.
* @minor: (out): Library minor version component.
* @micro: (out): Library micro version component.
*** 615,625 ****
* Return value: library version string.
*
* Since: 0.9.2
**/
const char *
! hb_version_string (void)
{
return HB_VERSION_STRING;
}
/**
--- 665,675 ----
* Return value: library version string.
*
* Since: 0.9.2
**/
const char *
! hb_version_string ()
{
return HB_VERSION_STRING;
}
/**
*** 727,777 ****
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
#endif
#ifdef USE_XLOCALE
! static HB_LOCALE_T C_locale;
! #ifdef HB_USE_ATEXIT
! static void
! free_C_locale (void)
{
! retry:
! HB_LOCALE_T locale = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
!
! if (!hb_atomic_ptr_cmpexch (&C_locale, locale, nullptr))
! goto retry;
! if (locale)
! HB_FREE_LOCALE (locale);
! }
#endif
! static HB_LOCALE_T
! get_C_locale (void)
! {
! retry:
! HB_LOCALE_T C = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
!
! if (unlikely (!C))
{
! C = HB_CREATE_LOCALE ("C");
!
! if (!hb_atomic_ptr_cmpexch (&C_locale, nullptr, C))
{
! HB_FREE_LOCALE (C_locale);
! goto retry;
}
! #ifdef HB_USE_ATEXIT
! atexit (free_C_locale); /* First person registers atexit() callback. */
#endif
- }
! return C;
}
! #endif
static bool
parse_float (const char **pp, const char *end, float *pv)
{
char buf[32];
--- 777,827 ----
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
#endif
#ifdef USE_XLOCALE
! #if HB_USE_ATEXIT
! static void free_static_C_locale ();
! #endif
! static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer (HB_LOCALE_T),
! hb_C_locale_lazy_loader_t>
{
! static HB_LOCALE_T create ()
! {
! HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
! #if HB_USE_ATEXIT
! atexit (free_static_C_locale);
#endif
! return C_locale;
! }
! static void destroy (HB_LOCALE_T p)
{
! HB_FREE_LOCALE (p);
! }
! static HB_LOCALE_T get_null ()
{
! return nullptr;
}
+ } static_C_locale;
! #if HB_USE_ATEXIT
! static
! void free_static_C_locale ()
! {
! static_C_locale.free_instance ();
! }
#endif
! static HB_LOCALE_T
! get_C_locale ()
! {
! return static_C_locale.get_unconst ();
}
! #endif /* USE_XLOCALE */
static bool
parse_float (const char **pp, const char *end, float *pv)
{
char buf[32];
*** 844,854 ****
quote = **pp;
(*pp)++;
}
const char *p = *pp;
! while (*pp < end && ISALNUM(**pp))
(*pp)++;
if (p == *pp || *pp - p > 4)
return false;
--- 894,904 ----
quote = **pp;
(*pp)++;
}
const char *p = *pp;
! while (*pp < end && (ISALNUM(**pp) || **pp == '_'))
(*pp)++;
if (p == *pp || *pp - p > 4)
return false;
*** 873,891 ****
{
parse_space (pp, end);
bool has_start;
! feature->start = 0;
! feature->end = (unsigned int) -1;
if (!parse_char (pp, end, '['))
return true;
has_start = parse_uint (pp, end, &feature->start);
! if (parse_char (pp, end, ':')) {
parse_uint (pp, end, &feature->end);
} else {
if (has_start)
feature->end = feature->start + 1;
}
--- 923,941 ----
{
parse_space (pp, end);
bool has_start;
! feature->start = HB_FEATURE_GLOBAL_START;
! feature->end = HB_FEATURE_GLOBAL_END;
if (!parse_char (pp, end, '['))
return true;
has_start = parse_uint (pp, end, &feature->start);
! if (parse_char (pp, end, ':') || parse_char (pp, end, ';')) {
parse_uint (pp, end, &feature->end);
} else {
if (has_start)
feature->end = feature->start + 1;
}
*** 1061,1072 ****
hb_tag_to_string (variation->tag, s + len);
len += 4;
while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
! len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", variation->value));
assert (len < ARRAY_LENGTH (s));
len = MIN (len, size - 1);
memcpy (buf, s, len);
buf[len] = '\0';
}
--- 1111,1131 ----
hb_tag_to_string (variation->tag, s + len);
len += 4;
while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
! len += MAX (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
assert (len < ARRAY_LENGTH (s));
len = MIN (len, size - 1);
memcpy (buf, s, len);
buf[len] = '\0';
}
+
+ /* If there is no visibility control, then hb-static.cc will NOT
+ * define anything. Instead, we get it to define one set in here
+ * only, so only libharfbuzz.so defines them, not other libs. */
+ #ifdef HB_NO_VISIBILITY
+ #undef HB_NO_VISIBILITY
+ #include "hb-static.cc"
+ #define HB_NO_VISIBILITY 1
+ #endif
< prev index next >