< 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 >