/* * Copyright © 2009,2010 Red Hat, Inc. * Copyright © 2011,2012 Google, Inc. * * This is part of HarfBuzz, a text shaping library. * * Permission is hereby granted, without written agreement and without * license or royalty fees, to use, copy, modify, and distribute this * software and its documentation for any purpose, provided that the * above copyright notice and the following two paragraphs appear in * all copies of this software. * * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * * Red Hat Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod */ #include "hb.hh" #include "hb-machinery.hh" /** * 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_tag_t */ /** * hb_tag_from_string: * @str: (array length=len) (element-type uint8_t): String to convert * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string into an #hb_tag_t. Valid tags * are four characters. Shorter input strings will be * padded with spaces. Longer input strings will be * truncated. * * Return value: The #hb_tag_t corresponding to @str * * Since: 0.9.2 **/ hb_tag_t hb_tag_from_string (const char *str, int len) { … } /** * hb_tag_to_string: * @tag: #hb_tag_t to convert * @buf: (out caller-allocates) (array fixed-size=4) (element-type uint8_t): Converted string * * Converts an #hb_tag_t to a string and returns it in @buf. * Strings will be four characters long. * * Since: 0.9.5 **/ void hb_tag_to_string (hb_tag_t tag, char *buf) { … } /* hb_direction_t */ static const char direction_strings[][4] = …; /** * hb_direction_from_string: * @str: (array length=len) (element-type uint8_t): String to convert * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string to an #hb_direction_t. * * Matching is loose and applies only to the first letter. For * examples, "LTR" and "left-to-right" will both return #HB_DIRECTION_LTR. * * Unmatched strings will return #HB_DIRECTION_INVALID. * * Return value: The #hb_direction_t matching @str * * Since: 0.9.2 **/ hb_direction_t hb_direction_from_string (const char *str, int len) { … } /** * hb_direction_to_string: * @direction: The #hb_direction_t to convert * * Converts an #hb_direction_t to a string. * * Return value: (transfer none): The string corresponding to @direction * * Since: 0.9.2 **/ const char * hb_direction_to_string (hb_direction_t direction) { … } /* hb_language_t */ struct hb_language_impl_t { … }; static const char canon_map[256] = …; static bool lang_equal (hb_language_t v1, const void *v2) { … } #if 0 static unsigned int lang_hash (const void *key) { const unsigned char *p = key; unsigned int h = 0; while (canon_map[*p]) { h = (h << 5) - h + canon_map[*p]; p++; } return h; } #endif struct hb_language_item_t { … }; /* Thread-safe lockfree language list */ static hb_atomic_ptr_t <hb_language_item_t> langs; static inline void free_langs () { … } static hb_language_item_t * lang_find_or_insert (const char *key) { … } /** * 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) { … } /** * hb_language_to_string: * @language: The #hb_language_t to convert * * Converts an #hb_language_t to a string. * * Return value: (transfer none): * A `NULL`-terminated string representing the @language. Must not be freed by * the caller. * * Since: 0.9.2 **/ const char * hb_language_to_string (hb_language_t language) { … } /** * hb_language_get_default: * * Fetch the default language from current locale. * * <note>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.</note> * * Return value: (transfer none): The default language of the locale as * an #hb_language_t * * Since: 0.9.2 **/ hb_language_t hb_language_get_default () { … } /** * hb_language_matches: * @language: The #hb_language_t to work on * @specific: Another #hb_language_t * * Check whether a second language tag is the same or a more * specific version of the provided language tag. For example, * "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR". * * Return value: `true` if languages match, `false` otherwise. * * Since: 5.0.0 **/ hb_bool_t hb_language_matches (hb_language_t language, hb_language_t specific) { … } /* hb_script_t */ /** * hb_script_from_iso15924_tag: * @tag: an #hb_tag_t representing an ISO 15924 tag. * * Converts an ISO 15924 script tag to a corresponding #hb_script_t. * * Return value: * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ hb_script_t hb_script_from_iso15924_tag (hb_tag_t tag) { … } /** * hb_script_from_string: * @str: (array length=len) (element-type uint8_t): a string representing an * ISO 15924 tag. * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts a string @str representing an ISO 15924 script tag to a * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then * hb_script_from_iso15924_tag(). * * Return value: * An #hb_script_t corresponding to the ISO 15924 tag. * * Since: 0.9.2 **/ hb_script_t hb_script_from_string (const char *str, int len) { … } /** * hb_script_to_iso15924_tag: * @script: an #hb_script_t to convert. * * Converts an #hb_script_t to a corresponding ISO 15924 script tag. * * Return value: * An #hb_tag_t representing an ISO 15924 script tag. * * Since: 0.9.2 **/ hb_tag_t hb_script_to_iso15924_tag (hb_script_t script) { … } /** * hb_script_get_horizontal_direction: * @script: The #hb_script_t to query * * Fetches the #hb_direction_t of a script when it is * set horizontally. All right-to-left scripts will return * #HB_DIRECTION_RTL. All left-to-right scripts will return * #HB_DIRECTION_LTR. Scripts that can be written either * horizontally or vertically will return #HB_DIRECTION_INVALID. * Unknown scripts will return #HB_DIRECTION_LTR. * * Return value: The horizontal #hb_direction_t of @script * * Since: 0.9.2 **/ hb_direction_t hb_script_get_horizontal_direction (hb_script_t script) { … } /* 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 * * Returns library version as three integer components. * * Since: 0.9.2 **/ void hb_version (unsigned int *major, unsigned int *minor, unsigned int *micro) { … } /** * hb_version_string: * * Returns library version as a string with three components. * * Return value: Library version string * * Since: 0.9.2 **/ const char * hb_version_string () { … } /** * hb_version_atleast: * @major: Library major version component * @minor: Library minor version component * @micro: Library micro version component * * Tests the library version against a minimum value, * as three integer components. * * Return value: `true` if the library is equal to or greater than * the test value, `false` otherwise * * Since: 0.9.30 **/ hb_bool_t hb_version_atleast (unsigned int major, unsigned int minor, unsigned int micro) { … } /* hb_feature_t and hb_variation_t */ static bool parse_space (const char **pp, const char *end) { … } static bool parse_char (const char **pp, const char *end, char c) { … } static bool parse_uint (const char **pp, const char *end, unsigned int *pv) { … } static bool parse_uint32 (const char **pp, const char *end, uint32_t *pv) { … } static bool parse_bool (const char **pp, const char *end, uint32_t *pv) { … } /* hb_feature_t */ static bool parse_feature_value_prefix (const char **pp, const char *end, hb_feature_t *feature) { … } static bool parse_tag (const char **pp, const char *end, hb_tag_t *tag) { … } static bool parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature) { … } static bool parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *feature) { … } static bool parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) { … } /** * hb_feature_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse * @len: length of @str, or -1 if string is `NULL` terminated * @feature: (out): the #hb_feature_t to initialize with the parsed values * * Parses a string into a #hb_feature_t. * * The format for specifying feature strings follows. All valid CSS * font-feature-settings values other than 'normal' and the global values are * also accepted, though not documented below. CSS string escapes are not * supported. * * The range indices refer to the positions between Unicode characters. The * position before the first character is always 0. * * The format is Python-esque. Here is how it all works: * * <informaltable pgwide='1' align='left' frame='none'> * <tgroup cols='5'> * <thead> * <row><entry>Syntax</entry> <entry>Value</entry> <entry>Start</entry> <entry>End</entry></row> * </thead> * <tbody> * <row><entry>Setting value:</entry></row> * <row><entry>kern</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row> * <row><entry>+kern</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row> * <row><entry>-kern</entry> <entry>0</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature off</entry></row> * <row><entry>kern=0</entry> <entry>0</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature off</entry></row> * <row><entry>kern=1</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row> * <row><entry>aalt=2</entry> <entry>2</entry> <entry>0</entry> <entry>∞</entry> <entry>Choose 2nd alternate</entry></row> * <row><entry>Setting index:</entry></row> * <row><entry>kern[]</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row> * <row><entry>kern[:]</entry> <entry>1</entry> <entry>0</entry> <entry>∞</entry> <entry>Turn feature on</entry></row> * <row><entry>kern[5:]</entry> <entry>1</entry> <entry>5</entry> <entry>∞</entry> <entry>Turn feature on, partial</entry></row> * <row><entry>kern[:5]</entry> <entry>1</entry> <entry>0</entry> <entry>5</entry> <entry>Turn feature on, partial</entry></row> * <row><entry>kern[3:5]</entry> <entry>1</entry> <entry>3</entry> <entry>5</entry> <entry>Turn feature on, range</entry></row> * <row><entry>kern[3]</entry> <entry>1</entry> <entry>3</entry> <entry>3+1</entry> <entry>Turn feature on, single char</entry></row> * <row><entry>Mixing it all:</entry></row> * <row><entry>aalt[3:5]=2</entry> <entry>2</entry> <entry>3</entry> <entry>5</entry> <entry>Turn 2nd alternate on for range</entry></row> * </tbody> * </tgroup> * </informaltable> * * Return value: * `true` if @str is successfully parsed, `false` otherwise * * Since: 0.9.5 **/ hb_bool_t hb_feature_from_string (const char *str, int len, hb_feature_t *feature) { … } /** * hb_feature_to_string: * @feature: an #hb_feature_t to convert * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * * Converts a #hb_feature_t into a `NULL`-terminated string in the format * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * * Since: 0.9.5 **/ void hb_feature_to_string (hb_feature_t *feature, char *buf, unsigned int size) { … } /* hb_variation_t */ static bool parse_variation_value (const char **pp, const char *end, hb_variation_t *variation) { … } static bool parse_one_variation (const char **pp, const char *end, hb_variation_t *variation) { … } /** * hb_variation_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse * @len: length of @str, or -1 if string is `NULL` terminated * @variation: (out): the #hb_variation_t to initialize with the parsed values * * Parses a string into a #hb_variation_t. * * The format for specifying variation settings follows. All valid CSS * font-variation-settings values other than 'normal' and 'inherited' are also * accepted, though, not documented below. * * The format is a tag, optionally followed by an equals sign, followed by a * number. For example `wght=500`, or `slnt=-7.5`. * * Return value: * `true` if @str is successfully parsed, `false` otherwise * * Since: 1.4.2 */ hb_bool_t hb_variation_from_string (const char *str, int len, hb_variation_t *variation) { … } #ifndef HB_NO_SETLOCALE static inline void free_static_C_locale (); 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 l = newlocale (LC_ALL_MASK, "C", NULL); if (!l) return l; hb_atexit (free_static_C_locale); return l; } static void destroy (hb_locale_t l) { freelocale (l); } static hb_locale_t get_null () { return (hb_locale_t) 0; } } static_C_locale; static inline void free_static_C_locale () { static_C_locale.free_instance (); } static hb_locale_t get_C_locale () { return static_C_locale.get_unconst (); } #endif /** * hb_variation_to_string: * @variation: an #hb_variation_t to convert * @buf: (array length=size) (out caller-allocates): output string * @size: the allocated size of @buf * * Converts an #hb_variation_t into a `NULL`-terminated string in the format * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * * Since: 1.4.2 */ void hb_variation_to_string (hb_variation_t *variation, char *buf, unsigned int size) { … } /** * hb_color_get_alpha: * @color: an #hb_color_t we are interested in its channels. * * Fetches the alpha channel of the given @color. * * Return value: Alpha channel value * * Since: 2.1.0 */ uint8_t (hb_color_get_alpha) (hb_color_t color) { … } /** * hb_color_get_red: * @color: an #hb_color_t we are interested in its channels. * * Fetches the red channel of the given @color. * * Return value: Red channel value * * Since: 2.1.0 */ uint8_t (hb_color_get_red) (hb_color_t color) { … } /** * hb_color_get_green: * @color: an #hb_color_t we are interested in its channels. * * Fetches the green channel of the given @color. * * Return value: Green channel value * * Since: 2.1.0 */ uint8_t (hb_color_get_green) (hb_color_t color) { … } /** * hb_color_get_blue: * @color: an #hb_color_t we are interested in its channels. * * Fetches the blue channel of the given @color. * * Return value: Blue channel value * * Since: 2.1.0 */ uint8_t (hb_color_get_blue) (hb_color_t color) { … } /* 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 … #endif