📄 fonts.c
字号:
desc->gravity = gravity; desc->mask |= PANGO_FONT_MASK_GRAVITY;}/** * pango_font_description_get_gravity: * @desc: a #PangoFontDescription * * Gets the gravity field of a font description. See * pango_font_description_set_gravity(). * * Return value: the gravity field for the font description. Use * pango_font_description_get_set_fields() to find out if * the field was explicitly set or not. * * Since: 1.16 **/PangoGravitypango_font_description_get_gravity (const PangoFontDescription *desc){ g_return_val_if_fail (desc != NULL, pfd_defaults.gravity); return desc->gravity;}/** * pango_font_description_get_set_fields: * @desc: a #PangoFontDescription * * Determines which fields in a font description have been set. * * Return value: a bitmask with bits set corresponding to the * fields in @desc that have been set. **/PangoFontMaskpango_font_description_get_set_fields (const PangoFontDescription *desc){ g_return_val_if_fail (desc != NULL, pfd_defaults.mask); return desc->mask;}/** * pango_font_description_unset_fields: * @desc: a #PangoFontDescription * @to_unset: bitmask of fields in the @desc to unset. * * Unsets some of the fields in a #PangoFontDescription. The unset * fields will get back to their default values. **/voidpango_font_description_unset_fields (PangoFontDescription *desc, PangoFontMask to_unset){ PangoFontDescription unset_desc; g_return_if_fail (desc != NULL); unset_desc = pfd_defaults; unset_desc.mask = to_unset; pango_font_description_merge_static (desc, &unset_desc, TRUE); desc->mask &= ~to_unset;}/** * pango_font_description_merge: * @desc: a #PangoFontDescription * @desc_to_merge: the #PangoFontDescription to merge from * @replace_existing: if %TRUE, replace fields in @desc with the * corresponding values from @desc_to_merge, even if they * are already exist. * * Merges the fields that are set in @desc_to_merge into the fields in * @desc. If @replace_existing is %FALSE, only fields in @desc that * are not already set are affected. If %TRUE, then fields that are * already set will be replaced as well. **/voidpango_font_description_merge (PangoFontDescription *desc, const PangoFontDescription *desc_to_merge, gboolean replace_existing){ gboolean family_merged = desc_to_merge->family_name && (replace_existing || !desc->family_name); pango_font_description_merge_static (desc, desc_to_merge, replace_existing); if (family_merged) { desc->family_name = g_strdup (desc->family_name); desc->static_family = FALSE; }}/** * pango_font_description_merge_static: * @desc: a #PangoFontDescription * @desc_to_merge: the #PangoFontDescription to merge from * @replace_existing: if %TRUE, replace fields in @desc with the * corresponding values from @desc_to_merge, even if they * are already exist. * * Like pango_font_description_merge(), but only a shallow copy is made * of the family name and other allocated fields. @desc can only be * used until @desc_to_merge is modified or freed. This is meant * to be used when the merged font description is only needed temporarily. **/voidpango_font_description_merge_static (PangoFontDescription *desc, const PangoFontDescription *desc_to_merge, gboolean replace_existing){ PangoFontMask new_mask; g_return_if_fail (desc != NULL); if (replace_existing) new_mask = desc_to_merge->mask; else new_mask = desc_to_merge->mask & ~desc->mask; if (new_mask & PANGO_FONT_MASK_FAMILY) pango_font_description_set_family_static (desc, desc_to_merge->family_name); if (new_mask & PANGO_FONT_MASK_STYLE) desc->style = desc_to_merge->style; if (new_mask & PANGO_FONT_MASK_VARIANT) desc->variant = desc_to_merge->variant; if (new_mask & PANGO_FONT_MASK_WEIGHT) desc->weight = desc_to_merge->weight; if (new_mask & PANGO_FONT_MASK_STRETCH) desc->stretch = desc_to_merge->stretch; if (new_mask & PANGO_FONT_MASK_SIZE) { desc->size = desc_to_merge->size; desc->size_is_absolute = desc_to_merge->size_is_absolute; } if (new_mask & PANGO_FONT_MASK_GRAVITY) desc->gravity = desc_to_merge->gravity; desc->mask |= new_mask;}static gintcompute_distance (const PangoFontDescription *a, const PangoFontDescription *b){ if (a->style == b->style) { return abs(a->weight - b->weight); } else if (a->style != PANGO_STYLE_NORMAL && b->style != PANGO_STYLE_NORMAL) { /* Equate oblique and italic, but with a big penalty */ return 1000000 + abs (a->weight - b->weight); } else return G_MAXINT;}/** * pango_font_description_better_match: * @desc: a #PangoFontDescription * @old_match: a #PangoFontDescription, or %NULL * @new_match: a #PangoFontDescription * * Determines if the style attributes of @new_match are a closer match * for @desc than @old_match, or if @old_match is %NULL, determines if * @new_match is a match at all. Approximate matching is done for * weight and style; other attributes must match exactly. * * Return value: %TRUE if @new_match is a better match **/gbooleanpango_font_description_better_match (const PangoFontDescription *desc, const PangoFontDescription *old_match, const PangoFontDescription *new_match){ g_return_val_if_fail (desc != NULL, G_MAXINT); g_return_val_if_fail (new_match != NULL, G_MAXINT); if (new_match->variant == desc->variant && new_match->stretch == desc->stretch && new_match->gravity == desc->gravity) { int old_distance = old_match ? compute_distance (desc, old_match) : G_MAXINT; int new_distance = compute_distance (desc, new_match); if (new_distance < old_distance) return TRUE; } return FALSE;}/** * pango_font_description_copy: * @desc: a #PangoFontDescription * * Make a copy of a #PangoFontDescription. * * Return value: the newly allocated #PangoFontDescription, which should * be freed with pango_font_description_free(). **/PangoFontDescription *pango_font_description_copy (const PangoFontDescription *desc){ PangoFontDescription *result = g_slice_new (PangoFontDescription); *result = *desc; if (result->family_name) { result->family_name = g_strdup (result->family_name); result->static_family = FALSE; } return result;}/** * pango_font_description_copy_static: * @desc: a #PangoFontDescription * * Like pango_font_description_copy(), but only a shallow copy is made * of the family name and other allocated fields. The result can only * be used until @desc is modified or freed. This is meant to be used * when the copy is only needed temporarily. * * Return value: the newly allocated #PangoFontDescription, which should * be freed with pango_font_description_free(). **/PangoFontDescription *pango_font_description_copy_static (const PangoFontDescription *desc){ PangoFontDescription *result = g_slice_new (PangoFontDescription); *result = *desc; if (result->family_name) result->static_family = TRUE; return result;}/** * pango_font_description_equal: * @desc1: a #PangoFontDescription * @desc2: another #PangoFontDescription * * Compares two font descriptions for equality. Two font descriptions * are considered equal if the fonts they describe are provably identical. * This means that their masks do not have to match, as long as other fields * are all the same. (Two font descriptions may result in identical fonts * being loaded, but still compare %FALSE.) * * Return value: %TRUE if the two font descriptions are identical, * %FALSE otherwise. **/gbooleanpango_font_description_equal (const PangoFontDescription *desc1, const PangoFontDescription *desc2){ g_return_val_if_fail (desc1 != NULL, FALSE); g_return_val_if_fail (desc2 != NULL, FALSE); return desc1->style == desc2->style && desc1->variant == desc2->variant && desc1->weight == desc2->weight && desc1->stretch == desc2->stretch && desc1->size == desc2->size && desc1->size_is_absolute == desc2->size_is_absolute && desc1->gravity == desc2->gravity && (desc1->family_name == desc2->family_name || (desc1->family_name && desc2->family_name && g_ascii_strcasecmp (desc1->family_name, desc2->family_name) == 0));}#define TOLOWER(c) \ (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' + 'a' : (c))static guintcase_insensitive_hash (const char *key){ const char *p = key; guint h = TOLOWER (*p); if (h) { for (p += 1; *p != '\0'; p++) h = (h << 5) - h + TOLOWER (*p); } return h;}/** * pango_font_description_hash: * @desc: a #PangoFontDescription * * Computes a hash of a #PangoFontDescription structure suitable * to be used, for example, as an argument to g_hash_table_new(). * The hash value is independent of @desc->mask. * * Return value: the hash value. **/guintpango_font_description_hash (const PangoFontDescription *desc){ guint hash = 0; if (desc->family_name) hash = case_insensitive_hash (desc->family_name); hash ^= desc->size; hash ^= desc->size_is_absolute ? 0xc33ca55a : 0; hash ^= desc->style << 16; hash ^= desc->variant << 18; hash ^= desc->weight << 16; hash ^= desc->stretch << 26; hash ^= desc->gravity << 28; return hash;}/** * pango_font_description_free: * @desc: a #PangoFontDescription * * Frees a font description. **/voidpango_font_description_free (PangoFontDescription *desc){ if (desc) { if (desc->family_name && !desc->static_family) g_free (desc->family_name); g_slice_free (PangoFontDescription, desc); }}/** * pango_font_descriptions_free: * @descs: a pointer to an array of #PangoFontDescription * @n_descs: number of font descriptions in @descs * * Frees a list of font descriptions from pango_font_map_list_fonts() **/voidpango_font_descriptions_free (PangoFontDescription **descs, int n_descs){ int i; if (descs) { for (i = 0; i<n_descs; i++) pango_font_description_free (descs[i]); g_free (descs); }}typedef struct{ int value; const char str[16];} FieldMap;static const FieldMap style_map[] = { { PANGO_STYLE_NORMAL, "" }, { PANGO_STYLE_OBLIQUE, "Oblique" }, { PANGO_STYLE_ITALIC, "Italic" }};static const FieldMap variant_map[] = { { PANGO_VARIANT_NORMAL, "" }, { PANGO_VARIANT_SMALL_CAPS, "Small-Caps" }};static const FieldMap weight_map[] = { { PANGO_WEIGHT_ULTRALIGHT, "Ultra-Light" }, { PANGO_WEIGHT_LIGHT, "Light" }, { PANGO_WEIGHT_NORMAL, "" }, { 500, "Medium" }, { PANGO_WEIGHT_SEMIBOLD, "Semi-Bold" }, { PANGO_WEIGHT_BOLD, "Bold" }, { PANGO_WEIGHT_ULTRABOLD, "Ultra-Bold" }, { PANGO_WEIGHT_HEAVY, "Heavy" }};static const FieldMap stretch_map[] = { { PANGO_STRETCH_ULTRA_CONDENSED, "Ultra-Condensed" }, { PANGO_STRETCH_EXTRA_CONDENSED, "Extra-Condensed" }, { PANGO_STRETCH_CONDENSED, "Condensed" }, { PANGO_STRETCH_SEMI_CONDENSED, "Semi-Condensed" }, { PANGO_STRETCH_NORMAL, "" }, { PANGO_STRETCH_SEMI_EXPANDED, "Semi-Expanded" }, { PANGO_STRETCH_EXPANDED, "Expanded" }, { PANGO_STRETCH_EXTRA_EXPANDED, "Extra-Expanded" }, { PANGO_STRETCH_ULTRA_EXPANDED, "Ultra-Expanded" }};static const FieldMap gravity_map[] = { { PANGO_GRAVITY_SOUTH, "Not-Rotated" }, { PANGO_GRAVITY_SOUTH, "South" }, { PANGO_GRAVITY_SOUTH, "Upside-Down" }, { PANGO_GRAVITY_NORTH, "North" }, { PANGO_GRAVITY_EAST, "Rotated-Left" }, { PANGO_GRAVITY_EAST, "East" }, { PANGO_GRAVITY_WEST, "Rotated-Right" }, { PANGO_GRAVITY_WEST, "West" }};static gbooleanfind_field (const FieldMap *map, int n_elements, const char *str, int len, int *val){ int i; for (i=0; i<n_elements; i++) { if (map[i].str[0] && g_ascii_strncasecmp (map[i].str, str, len) == 0 && map[i].str[len] == '\0') { if (val) *val = map[i].value; return TRUE; } } return FALSE;}static gbooleanfind_field_any (const char *str, int len, PangoFontDescription *desc){ gboolean found = FALSE; if (g_ascii_strcasecmp (str, "Normal") == 0) return TRUE;#define FIELD(NAME, MASK) \ G_STMT_START { \ if (find_field (NAME##_map, G_N_ELEMENTS (NAME##_map), str, len, \ desc ? (int *)&desc->NAME : NULL)) \ { \ found = TRUE; \ if (desc) \ desc->mask |= MASK; \ } \ } G_STMT_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -