/** * SECTION:hb-common * @title: hb-common * @short_description: Common data types * @include: hb.h * * Common data types used across HarfBuzz are defined here.
**/
/* This is idempotent and threadsafe. */
_hb_options = u.i;
}
/* 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 (constchar *str, int len)
{ char tag[4]; unsignedint i;
if (!str || !len || !*str) return HB_TAG_NONE;
if (len < 0 || len > 4)
len = 4; for (i = 0; i < (unsigned) len && str[i]; i++)
tag[i] = str[i]; for (; i < 4; i++)
tag[i] = ' ';
return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
}
/** * 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)
{
buf[0] = (char) (uint8_t) (tag >> 24);
buf[1] = (char) (uint8_t) (tag >> 16);
buf[2] = (char) (uint8_t) (tag >> 8);
buf[3] = (char) (uint8_t) (tag >> 0);
}
/** * 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 (constchar *str, int len)
{ if (unlikely (!str || !len || !*str)) return HB_DIRECTION_INVALID;
/* Lets match loosely: just match the first letter, such that * all of "ltr", "left-to-right", etc work!
*/ char c = TOLOWER (str[0]); for (unsignedint i = 0; i < ARRAY_LENGTH (direction_strings); i++) if (c == direction_strings[i][0]) return (hb_direction_t) (HB_DIRECTION_LTR + i);
return HB_DIRECTION_INVALID;
}
/** * 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
**/ constchar *
hb_direction_to_string (hb_direction_t direction)
{ if (likely ((unsignedint) (direction - HB_DIRECTION_LTR)
< ARRAY_LENGTH (direction_strings))) return direction_strings[direction - HB_DIRECTION_LTR];
if (!first_lang)
hb_atexit (free_langs); /* First person registers atexit() callback. */
return lang;
}
/** * 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 (constchar *str, int len)
{ if (!str || !len || !*str) return HB_LANGUAGE_INVALID;
/** * 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
**/ constchar *
hb_language_to_string (hb_language_t language)
{ if (unlikely (!language)) return nullptr;
return language->s;
}
/** * 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 ()
{ 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 (hb_setlocale (LC_CTYPE, nullptr), -1);
(void) default_language.cmpexch (HB_LANGUAGE_INVALID, language);
}
return language;
}
/** * 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)
{ if (language == specific) returntrue; if (!language || !specific) returnfalse;
/** * 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)
{ if (unlikely (tag == HB_TAG_NONE)) return HB_SCRIPT_INVALID;
/* Be lenient, adjust case (one capital letter followed by three small letters) */
tag = (tag & 0xDFDFDFDFu) | 0x00202020u;
switch (tag) {
/* These graduated from the 'Q' private-area codes, but * the old code is still aliased by Unicode, and the Qaai
* one in use by ICU. */ case HB_TAG('Q','a','a','i'): return HB_SCRIPT_INHERITED; case HB_TAG('Q','a','a','c'): return HB_SCRIPT_COPTIC;
/* Script variants from https://unicode.org/iso15924/ */ case HB_TAG('A','r','a','n'): return HB_SCRIPT_ARABIC; case HB_TAG('C','y','r','s'): return HB_SCRIPT_CYRILLIC; case HB_TAG('G','e','o','k'): return HB_SCRIPT_GEORGIAN; case HB_TAG('H','a','n','s'): return HB_SCRIPT_HAN; case HB_TAG('H','a','n','t'): return HB_SCRIPT_HAN; case HB_TAG('J','a','m','o'): return HB_SCRIPT_HANGUL; case HB_TAG('L','a','t','f'): return HB_SCRIPT_LATIN; case HB_TAG('L','a','t','g'): return HB_SCRIPT_LATIN; case HB_TAG('S','y','r','e'): return HB_SCRIPT_SYRIAC; case HB_TAG('S','y','r','j'): return HB_SCRIPT_SYRIAC; case HB_TAG('S','y','r','n'): return HB_SCRIPT_SYRIAC;
}
/* If it looks right, just use the tag as a script */ if (((uint32_t) tag & 0xE0E0E0E0u) == 0x40606060u) return (hb_script_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 (constchar *str, int len)
{ return hb_script_from_iso15924_tag (hb_tag_from_string (str, 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)
{ return (hb_tag_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)
{ /* https://docs.google.com/spreadsheets/d/1Y90M0Ie3MUJ6UVCRDOypOtijlMDLNNyyLk36T6iMu0o */ switch ((hb_tag_t) script)
{ /* Unicode-1.1 additions */ case HB_SCRIPT_ARABIC: case HB_SCRIPT_HEBREW:
/* Unicode-3.0 additions */ case HB_SCRIPT_SYRIAC: case HB_SCRIPT_THAANA:
/* Unicode-4.0 additions */ case HB_SCRIPT_CYPRIOT:
/* Unicode-4.1 additions */ case HB_SCRIPT_KHAROSHTHI:
/* Unicode-5.0 additions */ case HB_SCRIPT_PHOENICIAN: case HB_SCRIPT_NKO:
/* Unicode-5.1 additions */ case HB_SCRIPT_LYDIAN:
/* Unicode-5.2 additions */ case HB_SCRIPT_AVESTAN: case HB_SCRIPT_IMPERIAL_ARAMAIC: case HB_SCRIPT_INSCRIPTIONAL_PAHLAVI: case HB_SCRIPT_INSCRIPTIONAL_PARTHIAN: case HB_SCRIPT_OLD_SOUTH_ARABIAN: case HB_SCRIPT_OLD_TURKIC: case HB_SCRIPT_SAMARITAN:
/* Unicode-6.0 additions */ case HB_SCRIPT_MANDAIC:
/* Unicode-6.1 additions */ case HB_SCRIPT_MEROITIC_CURSIVE: case HB_SCRIPT_MEROITIC_HIEROGLYPHS:
/* Unicode-7.0 additions */ case HB_SCRIPT_MANICHAEAN: case HB_SCRIPT_MENDE_KIKAKUI: case HB_SCRIPT_NABATAEAN: case HB_SCRIPT_OLD_NORTH_ARABIAN: case HB_SCRIPT_PALMYRENE: case HB_SCRIPT_PSALTER_PAHLAVI:
/* Unicode-8.0 additions */ case HB_SCRIPT_HATRAN:
/* Unicode-9.0 additions */ case HB_SCRIPT_ADLAM:
/* Unicode-11.0 additions */ case HB_SCRIPT_HANIFI_ROHINGYA: case HB_SCRIPT_OLD_SOGDIAN: case HB_SCRIPT_SOGDIAN:
/* Unicode-12.0 additions */ case HB_SCRIPT_ELYMAIC:
/* Unicode-13.0 additions */ case HB_SCRIPT_CHORASMIAN: case HB_SCRIPT_YEZIDI:
/* Unicode-14.0 additions */ case HB_SCRIPT_OLD_UYGHUR:
/* Unicode-16.0 additions */ case HB_SCRIPT_GARAY:
/** * 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 (unsignedint *major, unsignedint *minor, unsignedint *micro)
{
*major = HB_VERSION_MAJOR;
*minor = HB_VERSION_MINOR;
*micro = HB_VERSION_MICRO;
}
/** * hb_version_string: * * Returns library version as a string with three components. * * Return value: Library version string * * Since: 0.9.2
**/ constchar *
hb_version_string ()
{ return 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 (unsignedint major, unsignedint minor, unsignedint micro)
{ return HB_VERSION_ATLEAST (major, minor, micro);
}
/* hb_feature_t and hb_variation_t */
staticbool
parse_space (constchar **pp, constchar *end)
{ while (*pp < end && ISSPACE (**pp))
(*pp)++; returntrue;
}
staticbool
parse_uint (constchar **pp, constchar *end, unsignedint *pv)
{ /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
* such that -1 turns into "big number"... */ int v; if (unlikely (!hb_parse_int (pp, end, &v))) returnfalse;
*pv = v; returntrue;
}
staticbool
parse_uint32 (constchar **pp, constchar *end, uint32_t *pv)
{ /* Intentionally use hb_parse_int inside instead of hb_parse_uint,
* such that -1 turns into "big number"... */ int v; if (unlikely (!hb_parse_int (pp, end, &v))) returnfalse;
if (quote)
{ /* CSS expects exactly four bytes. And we only allow quotations for
* CSS compatibility. So, enforce the length. */ if (*pp - p != 4) returnfalse; if (*pp == end || **pp != quote) returnfalse;
(*pp)++;
}
staticbool
parse_feature_value_postfix (constchar **pp, constchar *end, hb_feature_t *feature)
{ bool had_equal = parse_char (pp, end, '='); bool had_value = parse_uint32 (pp, end, &feature->value) ||
parse_bool (pp, end, &feature->value); /* CSS doesn't use equal-sign between tag and value. * If there was an equal-sign, then there *must* be a value.
* A value without an equal-sign is ok, but not required. */ return !had_equal || had_value;
}
/** * 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 (constchar *str, int len,
hb_feature_t *feature)
{
hb_feature_t feat;
if (len < 0)
len = strlen (str);
if (likely (parse_one_feature (&str, str + len, &feat)))
{ if (feature)
*feature = feat; returntrue;
}
if (feature)
hb_memset (feature, 0, sizeof (*feature)); returnfalse;
}
/** * 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, unsignedint size)
{ if (unlikely (!size)) return;
char s[128]; unsignedint len = 0; if (feature->value == 0)
s[len++] = '-';
hb_tag_to_string (feature->tag, s + len);
len += 4; while (len && s[len - 1] == ' ')
len--; if (feature->start != HB_FEATURE_GLOBAL_START || feature->end != HB_FEATURE_GLOBAL_END)
{
s[len++] = '['; if (feature->start)
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->start)); if (feature->end != feature->start + 1) {
s[len++] = ':'; if (feature->end != HB_FEATURE_GLOBAL_END)
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%u", feature->end));
}
s[len++] = ']';
} if (feature->value > 1)
{
s[len++] = '=';
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%" PRIu32, feature->value));
}
assert (len < ARRAY_LENGTH (s));
len = hb_min (len, size - 1);
hb_memcpy (buf, s, len);
buf[len] = '\0';
}
/** * 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 (constchar *str, int len,
hb_variation_t *variation)
{
hb_variation_t var;
if (len < 0)
len = strlen (str);
if (likely (parse_one_variation (&str, str + len, &var)))
{ if (variation)
*variation = var; returntrue;
}
if (variation)
hb_memset (variation, 0, sizeof (*variation)); returnfalse;
}
/** * 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, unsignedint size)
{ if (unlikely (!size)) return;
char s[128]; unsignedint len = 0;
hb_tag_to_string (variation->tag, s + len);
len += 4; while (len && s[len - 1] == ' ')
len--;
s[len++] = '=';
hb_locale_t oldlocale HB_UNUSED;
oldlocale = hb_uselocale (get_C_locale ());
len += hb_max (0, snprintf (s + len, ARRAY_LENGTH (s) - len, "%g", (double) variation->value));
(void) hb_uselocale (oldlocale);
/** * 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)
{ return hb_color_get_alpha (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)
{ return hb_color_get_red (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)
{ return hb_color_get_green (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)
{ return hb_color_get_blue (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 1 #endif
Messung V0.5
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.