/* Pango * fonts.c: * * Copyright (C) 1999 Red Hat Software * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include #include #include #include #include "pango-types.h" #include "pango-font.h" #include "pango-fontmap.h" #include "pango-utils.h" struct _PangoFontDescription { char *family_name; PangoStyle style; PangoVariant variant; PangoWeight weight; PangoStretch stretch; guint16 mask; guint static_family : 1; int size; }; GType pango_font_description_get_type (void) { static GType our_type = 0; if (our_type == 0) our_type = g_boxed_type_register_static ("PangoFontDescription", (GBoxedCopyFunc)pango_font_description_copy, (GBoxedFreeFunc)pango_font_description_free); return our_type; } /** * pango_font_description_new: * * Creates a new font description structure with all fields unset. * * Return value: the newly created #PangoFontDescription. Use * pango_font_description_free to free the result. **/ PangoFontDescription * pango_font_description_new (void) { PangoFontDescription *desc = g_new (PangoFontDescription, 1); desc->mask = 0; desc->family_name = NULL; desc->style = PANGO_STYLE_NORMAL; desc->variant = PANGO_VARIANT_NORMAL; desc->weight = PANGO_WEIGHT_NORMAL; desc->stretch = PANGO_STRETCH_NORMAL; desc->size = 0; return desc; } /** * pango_font_description_set_family: * @desc: a #PangoFontDescription. * @family: a string representing the family name. * * Sets the family name field of a font description. The family * name represents a family of related font styles, and will * resolve to a particular #PangoFontFamily. In some uses of * #PangoFontDescription, it is also possible to use a comma * separated list of family names for this field. **/ void pango_font_description_set_family (PangoFontDescription *desc, const char *family) { g_return_if_fail (desc != NULL); if (desc->family_name == family) return; if (desc->family_name && !desc->static_family) g_free (desc->family_name); if (family) { desc->family_name = g_strdup (family); desc->mask |= PANGO_FONT_MASK_FAMILY; desc->static_family = FALSE; } else { desc->family_name = NULL; desc->mask &= ~PANGO_FONT_MASK_FAMILY; } } /** * pango_font_description_set_family_static: * @desc: a #PangoFontDescription * @family: a string representing the family name. * * Like pango_font_description_set_family(), except that no * copy of @family is made. The caller must make sure that the * string passed in stays around until @desc has been freed * or the name is set again. This function can be used if * @family is a static string such as a C string literal, or * if @desc is only needed temporarily. **/ void pango_font_description_set_family_static (PangoFontDescription *desc, const char *family) { g_return_if_fail (desc != NULL); if (desc->family_name == family) return; if (desc->family_name && !desc->static_family) g_free (desc->family_name); if (family) { desc->family_name = (char *)family; desc->mask |= PANGO_FONT_MASK_FAMILY; desc->static_family = TRUE; } else { desc->family_name = NULL; desc->mask &= ~PANGO_FONT_MASK_FAMILY; } } /** * pango_font_description_get_family: * @desc: a #PangoFontDescription. * * Gets the family name field of a font description. See * pango_font_description_set_family(). * * Return value: The family name field. (Will be %NULL if not previously set.) **/ G_CONST_RETURN char * pango_font_description_get_family (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, NULL); return desc->family_name; } /** * pango_font_description_set_style: * @desc: a #PangoFontDescription * @style: the style for the font description * * Sets the style field of a #PangoFontDescription. The * #PangoStyle enumeration describes whether the font is slanted and * the manner in which it is slanted; it can be either * %PANGO_STYLE_NORMAL, %PANGO_STYLE_ITALIC, or %PANGO_STYLE_OBLIQUE. * Most fonts will either have a italic style or an oblique * style, but not both, and font matching in Pango will * match italic specifications with oblique fonts and vice-versa * if an exact match is not found. **/ void pango_font_description_set_style (PangoFontDescription *desc, PangoStyle style) { g_return_if_fail (desc != NULL); desc->style = style; desc->mask |= PANGO_FONT_MASK_STYLE; } /** * pango_font_description_get_style: * @desc: a #PangoFontDescription * * Gets the style field of a #PangoFontDescription. See * pango_font_description_set_style(). * * Return value: the style field for the font description. * Use pango_font_description_get_set_fields() to find out if * the field was explicitely set or not. **/ PangoStyle pango_font_description_get_style (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, PANGO_STYLE_NORMAL); return desc->style; } /** * pango_font_description_set_variant: * @desc: a #PangoFontDescription * @variant: the variant type for the font description. * * Sets the variant field of a font description. The %PangoVariant * can either by %PANGO_VARIANT_NORMAL or %PANGO_VARIANT_SMALL_CAPS. **/ void pango_font_description_set_variant (PangoFontDescription *desc, PangoVariant variant) { g_return_if_fail (desc != NULL); desc->variant = variant; desc->mask |= PANGO_FONT_MASK_VARIANT; } /** * pango_font_description_get_variant: * @desc: a #PangoFontDescription. * * Gets the variant field of a #PangoFontDescription. See * pango_font_description_set_variant(). * * Return value: the variant field for the font description. Use * pango_font_description_get_set_fields() to find out if * the field was explicitely set or not. **/ PangoVariant pango_font_description_get_variant (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, PANGO_VARIANT_NORMAL); return desc->variant; } /** * pango_font_description_set_weight: * @desc: a #PangoFontDescription * @weight: the weight for the font description. * * Sets the weight field of a font description. The weight field * specifies how bold or light the font should be. In addition * to the values of the #PangoWeight enumeration, other intermediate * numeric values are possible. **/ void pango_font_description_set_weight (PangoFontDescription *desc, PangoWeight weight) { g_return_if_fail (desc != NULL); desc->weight = weight; desc->mask |= PANGO_FONT_MASK_WEIGHT; } /** * pango_font_description_get_weight: * @desc: a #PangoFontDescription * * Gets the weight field of a font description. See * pango_font_description_set_weight(). * * Return value: the weight field for the font description. Use * pango_font_description_get_set_fields() to find out if * the field was explicitely set or not. **/ PangoWeight pango_font_description_get_weight (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, PANGO_WEIGHT_NORMAL); return desc->weight; } /** * pango_font_description_set_stretch: * @desc: a #PangoFontDescription * @stretch: the stretch for the font description * * Sets the stretch field of a font description. The stretch field * specifes how narrow or wide the font should be. **/ void pango_font_description_set_stretch (PangoFontDescription *desc, PangoStretch stretch) { g_return_if_fail (desc != NULL); desc->stretch = stretch; desc->mask |= PANGO_FONT_MASK_STRETCH; } /** * pango_font_description_get_stretch: * @desc: a #PangoFontDescription. * * Gets the stretch field of a font description. * See pango_font_description_set_stretch(). * * Return value: the stretch field for the font description. Use * pango_font_description_get_set_fields() to find out if * the field was explicitely set or not. **/ PangoStretch pango_font_description_get_stretch (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, PANGO_STRETCH_NORMAL); return desc->stretch; } /** * pango_font_description_set_size: * @desc: a #PangoFontDescription * @size: the size for the font description in pango units. * (PANGO_SCALE pango units equals one point) * * Sets the size field of a font description. **/ void pango_font_description_set_size (PangoFontDescription *desc, gint size) { g_return_if_fail (desc != NULL); desc->size = size; desc->mask |= PANGO_FONT_MASK_SIZE; } /** * pango_font_description_get_size: * @desc: a #PangoFontDescription * * Gets the size field of a font description. * See pango_font_description_get_size(). * * Return value: the size field for the font description in pango * units. (PANGO_SCALE pango units equals one point). Returns 0 if * the stretch field has not previously been set. * pango_font_description_get_set_fields() to find out if the field * was explicitely set or not. **/ gint pango_font_description_get_size (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, 0); return desc->size; } /** * 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. **/ PangoFontMask pango_font_description_get_set_fields (const PangoFontDescription *desc) { g_return_val_if_fail (desc != NULL, 0); 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. Note that * this merely marks the fields cleared, it does not clear the * settings for those fields, to clear a family name set with * pango_font_description_set_family_static() so that it won't * be returned by subsequent calls to pango_font_description_get_family(), * you must actually call pango_font_description-set_family (desc, NULL); **/ void pango_font_description_unset_fields (PangoFontDescription *desc, PangoFontMask to_unset) { g_return_if_fail (desc != NULL); 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. * * Merge 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. **/ void pango_font_description_merge (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 (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; } /** * 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. **/ void pango_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; } static gint compute_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 #PangoFontDecription * @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 **/ gboolean pango_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) { 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: a newly allocated #PangoFontDescription. This value * must be freed using pango_font_description_free(). **/ PangoFontDescription * pango_font_description_copy (const PangoFontDescription *desc) { PangoFontDescription *result = g_new (PangoFontDescription, 1); *result = *desc; 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 modififed or freed. This is meant to be used * when the copy is only needed temporarily. * * Return value: a newly allocated #PangoFontDescription. This value * must be freed using pango_font_description_free(). **/ PangoFontDescription * pango_font_description_copy_static (const PangoFontDescription *desc) { PangoFontDescription *result = g_new (PangoFontDescription, 1); *result = *desc; result->static_family = TRUE; return result; } /** * pango_font_description_equal: * @desc1: a #PangoFontDescription * @desc2: another #PangoFontDescription * * Compare two font descriptions for equality. * * Return value: %TRUE if the two font descriptions are proveably * identical. (Two font descriptions may result in * identical fonts being loaded, but still compare * %FALSE.) **/ gboolean pango_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->mask == desc2->mask && desc1->style == desc2->style && desc1->variant == desc2->variant && desc1->weight == desc2->weight && desc1->stretch == desc2->stretch && desc1->size == desc2->size && (desc1->family_name == desc2->family_name || (desc1->family_name && desc2->family_name && g_strcasecmp (desc1->family_name, desc2->family_name) == 0))); } /** * pango_font_description_hash: * @desc: a #PangoFontDescription * * Compute a hash of a #PangoFontDescription structure suitable * to be used, for example, as an argument to g_hash_table_new(). * * Return value: the hash value. **/ guint pango_font_description_hash (const PangoFontDescription *desc) { guint hash = 0; hash = desc->mask; if (desc->mask & PANGO_FONT_MASK_FAMILY) hash = g_str_hash (desc->family_name); if (desc->mask & PANGO_FONT_MASK_SIZE) hash ^= desc->size; if (desc->mask & PANGO_FONT_MASK_STYLE) hash ^= desc->style << 16; if (desc->mask & PANGO_FONT_MASK_VARIANT) hash ^= desc->variant << 18; if (desc->mask & PANGO_FONT_MASK_WEIGHT) hash ^= desc->weight << 16; if (desc->mask & PANGO_FONT_MASK_STRETCH) hash ^= desc->stretch << 26; return hash; } /** * pango_font_description_free: * @desc: a #PangoFontDescription * * Free a font description returned from pango_font_describe() * or pango_font_description_copy(). **/ void pango_font_description_free (PangoFontDescription *desc) { if (desc) { if (desc->family_name && !desc->static_family) g_free (desc->family_name); g_free (desc); } } /** * pango_font_descriptions_free: * @descs: a pointer to an array of #PangoFontDescription * @n_descs: number of font descriptions in @descs * * Free a list of font descriptions from pango_font_map_list_fonts() **/ void pango_font_descriptions_free (PangoFontDescription **descs, int n_descs) { int i; if (descs) { for (i = 0; istyle : NULL) || find_field (variant_map, G_N_ELEMENTS (variant_map), str, len, desc ? (int *)&desc->variant : NULL) || find_field (weight_map, G_N_ELEMENTS (weight_map), str, len, desc ? (int *)&desc->weight : NULL) || find_field (stretch_map, G_N_ELEMENTS (stretch_map), str, len, desc ? (int *)&desc->stretch : NULL)); } static const char * getword (const char *str, const char *last, size_t *wordlen) { const char *result; while (last > str && isspace (*(last - 1))) last--; result = last; while (result > str && !isspace (*(result - 1))) result--; *wordlen = last - result; return result; } /** * pango_font_description_from_string: * @str: string reprentation of a font description. * * Create a new font description from a string representation in the * form "[FAMILY-LIST] [STYLE-OPTIONS] [SIZE]", where FAMILY-LIST is a * comma separated list of families optionally terminated by a comma, * STYLE_OPTIONS is a whitespace separated list of words where each * WORD describes one of style, variant, weight, or stretch, and SIZE * is an decimal number (size in points). Any one of the options may * be absent. If FAMILY-LIST is absent, then the family_name field of * the resulting font description will be initialized to NULL. If * STYLE-OPTIONS is missing, then all style options will be set to the * default values. If SIZE is missing, the size in the resulting font * description will be set to 0. * * Return value: a new #PangoFontDescription, or %NULL if the * string could not be parsed. **/ PangoFontDescription * pango_font_description_from_string (const char *str) { PangoFontDescription *desc; const char *p, *last; size_t len, wordlen; g_return_val_if_fail (str != NULL, NULL); desc = g_new (PangoFontDescription, 1); desc->mask = PANGO_FONT_MASK_STYLE | PANGO_FONT_MASK_WEIGHT | PANGO_FONT_MASK_VARIANT | PANGO_FONT_MASK_STRETCH; desc->family_name = NULL; desc->style = PANGO_STYLE_NORMAL; desc->weight = PANGO_WEIGHT_NORMAL; desc->variant = PANGO_VARIANT_NORMAL; desc->stretch = PANGO_STRETCH_NORMAL; desc->size = 0; len = strlen (str); last = str + len; p = getword (str, last, &wordlen); /* Look for a size at the end of the string */ if (wordlen != 0) { char *end; double size = g_strtod (p, &end); if (end - p == wordlen) /* word is a valid float */ { desc->size = (int)(size * PANGO_SCALE + 0.5); desc->mask |= PANGO_FONT_MASK_SIZE; last = p; } } /* Now parse style words */ p = getword (str, last, &wordlen); while (wordlen != 0) { if (!find_field_any (p, wordlen, desc)) break; else { last = p; p = getword (str, last, &wordlen); } } /* Remainder (str => p) is family list. Trim off trailing commas and leading and trailing white space */ while (last > str && isspace (*(last - 1))) last--; if (last > str && *(last - 1) == ',') last--; while (last > str && isspace (*(last - 1))) last--; while (isspace (*str)) str++; if (str != last) { desc->family_name = g_strndup (str, last - str); desc->mask |= PANGO_FONT_MASK_FAMILY; } return desc; } static void append_field (GString *str, FieldMap *map, int n_elements, int val) { int i; for (i=0; ilen > 0 && str->str[str->len -1] != ' ') g_string_append_c (str, ' '); g_string_append (str, map[i].str); } return; } } if (str->len > 0 || str->str[str->len -1] != ' ') g_string_append_c (str, ' '); g_string_append_printf (str, "%d", val); } /** * pango_font_description_to_string: * @desc: a #PangoFontDescription * * Create a string representation of a font description. See * pango_font_description_from_string() for a description of the * format of the string representation. The family list in the * string description will only have a terminating comma if the * last word of the list is a valid style option. * * Return value: a new string that must be freed with g_free(). **/ char * pango_font_description_to_string (const PangoFontDescription *desc) { GString *result = g_string_new (NULL); char *str; if (desc->family_name) { const char *p; size_t wordlen; g_string_append (result, desc->family_name); p = getword (desc->family_name, desc->family_name + strlen(desc->family_name), &wordlen); if (wordlen != 0 && find_field_any (p, wordlen, NULL)) g_string_append_c (result, ','); } append_field (result, weight_map, G_N_ELEMENTS (weight_map), desc->weight); append_field (result, style_map, G_N_ELEMENTS (style_map), desc->style); append_field (result, stretch_map, G_N_ELEMENTS (stretch_map), desc->stretch); append_field (result, variant_map, G_N_ELEMENTS (variant_map), desc->variant); if (result->len == 0) g_string_append (result, "Normal"); if (desc->mask & PANGO_FONT_MASK_SIZE) { if (result->len > 0 || result->str[result->len -1] != ' ') g_string_append_c (result, ' '); /* FIXME: %g is not right here. We need to always use '. */ g_string_append_printf (result, "%g", (double)desc->size / PANGO_SCALE); } str = result->str; g_string_free (result, FALSE); return str; } /** * pango_font_description_to_filename: * @desc: a #PangoFontDescription * * Create a filename representation of a font description. The * filename is identical to the result from calling * pango_font_description_to_string(), but with underscores instead of * characters that are untypical in filenames, and in lower case only. * * Return value: a new string that must be freed with g_free(). **/ char * pango_font_description_to_filename (const PangoFontDescription *desc) { char *result = pango_font_description_to_string (desc); char *p; g_strdown (result); p = result; while (*p) { if (strchr ("-+_.", *p) == NULL && !isalnum (*p)) *p = '_'; p++; } return result; } GType pango_font_get_type (void) { static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (PangoFontClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, NULL, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoFont), 0, /* n_preallocs */ NULL /* init */ }; object_type = g_type_register_static (G_TYPE_OBJECT, "PangoFont", &object_info, 0); } return object_type; } /** * pango_font_describe: * @font: a #PangoFont * * Return a description of the font. * * Return value: a newly allocated #PangoFontDescription object. **/ PangoFontDescription * pango_font_describe (PangoFont *font) { g_return_val_if_fail (font != NULL, NULL); return PANGO_FONT_GET_CLASS (font)->describe (font); } /** * pango_font_get_coverage: * @font: a #PangoFont * @language: the language tag * * Compute the coverage map for a given font and language tag. * * Return value: a newly allocated #PangoContext object. **/ PangoCoverage * pango_font_get_coverage (PangoFont *font, PangoLanguage *language) { g_return_val_if_fail (font != NULL, NULL); return PANGO_FONT_GET_CLASS (font)->get_coverage (font, language); } /** * pango_font_find_shaper: * @font: a #PangoFont * @language: the language tag * @ch: the ISO-10646 character code. * * Find the best matching shaper for a font for a particular * language tag and character point. * * Return value: the best matching shaper. **/ PangoEngineShape * pango_font_find_shaper (PangoFont *font, PangoLanguage *language, guint32 ch) { PangoEngineShape* shaper; g_return_val_if_fail (font != NULL, NULL); shaper = PANGO_FONT_GET_CLASS (font)->find_shaper (font, language, ch); return shaper; } /** * pango_font_get_glyph_extents: * @font: a #PangoFont * @glyph: the glyph index * @ink_rect: rectangle used to store the extents of the glyph as drawn * or %NULL to indicate that the result is not needed. * @logical_rect: rectangle used to store the logical extents of the glyph * or %NULL to indicate that the result is not needed. * * Get the logical and ink extents of a glyph within a font. The * coordinate system for each rectangle has its origin at the * base line and horizontal origin of the character with increasing * coordinates extending to the right and down. The macros PANGO_ASCENT(), * PANGO_DESCENT(), PANGO_LBEARING(), and PANGO_RBEARING can be used to convert * from the extents rectangle to more traditional font metrics. The units * of the rectangles are in 1/PANGO_SCALE of a device unit. **/ void pango_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { g_return_if_fail (font != NULL); PANGO_FONT_GET_CLASS (font)->get_glyph_extents (font, glyph, ink_rect, logical_rect); } /** * pango_font_get_metrics: * @font: a #PangoFont * @language: language tag used to determine which script to get the metrics * for, or %NULL to indicate to get the metrics for the entire * font. * * Get overall metric information for a font. Since the metrics may be * substantially different for different scripts, a language tag can * be provided to indicate that the metrics should be retrieved that * correspond to the script(s) used by that language. * * Returns: a #PangoMetrics object. The caller must call pango_font_metrics_unref() * when finished using the object. **/ PangoFontMetrics * pango_font_get_metrics (PangoFont *font, PangoLanguage *language) { return PANGO_FONT_GET_CLASS (font)->get_metrics (font, language); } GType pango_font_metrics_get_type (void) { static GType our_type = 0; if (our_type == 0) our_type = g_boxed_type_register_static ("PangoFontMetrics", (GBoxedCopyFunc)pango_font_metrics_ref, (GBoxedFreeFunc)pango_font_metrics_unref); return our_type; } /** * pango_font_metrics_new: * * Creates a new #PangoFontMetrics structure. This is only for * internal use by Pango backends and there is no public way * to set the fields of the structure. * * Return value: a newly created #PangoFontMetrics structure * with a reference count of 1. **/ PangoFontMetrics * pango_font_metrics_new (void) { PangoFontMetrics *metrics = g_new0 (PangoFontMetrics, 1); metrics->ref_count = 1; return metrics; } /** * pango_font_metrics_ref: * @metrics: a #PangoFontMetrics structure * * Increases the reference count of a font metrics structure. * * Return value: @metrics **/ PangoFontMetrics * pango_font_metrics_ref (PangoFontMetrics *metrics) { g_return_val_if_fail (metrics != NULL, NULL); metrics->ref_count++; return metrics; } /** * pango_font_metrics_unref: * @metrics: a #PangoFontMetrics structure * * Decreases the reference count of a font metrics structure. If * the result is zero, frees the structure and any associated * memory. **/ void pango_font_metrics_unref (PangoFontMetrics *metrics) { g_return_if_fail (metrics != NULL); g_return_if_fail (metrics->ref_count > 0 ); metrics->ref_count--; if (metrics->ref_count == 0) g_free (metrics); } /** * pango_font_metrics_get_ascent: * @metrics: a #PangoFontMetrics structure * * Gets the ascent from a font metrics structure. The ascent is * the distance from the baseline to the logical top of a line * of text. (The logical top may be above or below the top of the * actual drawn ink. It is necessary to lay out the text to figure * where the ink will be.) * * Return value: the ascent, in pango units. (1 point == PANGO_SCALE pango units.) **/ int pango_font_metrics_get_ascent (PangoFontMetrics *metrics) { g_return_val_if_fail (metrics != NULL, 0); return metrics->ascent; } /** * pango_font_metrics_get_descent: * @metrics: a #PangoFontMetrics structure * * Gets the descent from a font metrics structure. The descent is * the distance from the baseline to the logical bottom of a line * of text. (The logical bottom may be above or below the bottom of the * actual drawn ink. It is necessary to lay out the text to figure * where the ink will be.) * * Return value: the descent, in pango units. (1 point == PANGO_SCALE pango units.) **/ int pango_font_metrics_get_descent (PangoFontMetrics *metrics) { g_return_val_if_fail (metrics != NULL, 0); return metrics->descent; } /** * pango_font_metrics_get_approximate_char_width: * @metrics: a #PangoFontMetrics structure * * Gets the approximate character width for a font metrics structure. * This is merely a representative value useful, for example, for * determining the initial size for a window. Actual characters in * text will be wider and narrower than this. * * Return value: the character width, in pango units. (1 point == PANGO_SCALE pango units.) **/ int pango_font_metrics_get_approximate_char_width (PangoFontMetrics *metrics) { g_return_val_if_fail (metrics != NULL, 0); return metrics->approximate_char_width; } /** * pango_font_metrics_get_approximate_digit_width: * @metrics: a #PangoFontMetrics structure * * Gets the approximate digit width for a font metrics structure. * This is merely a representative value useful, for example, for * determining the initial size for a window. Actual digits in * text can be wider and narrower than this, though this value * is generally somewhat more accurate than the result of * pango_font_metrics_get_approximate_digit_width(). * * Return value: the digit width, in pango units. (1 point == PANGO_SCALE pango units.) **/ int pango_font_metrics_get_approximate_digit_width (PangoFontMetrics *metrics) { g_return_val_if_fail (metrics != NULL, 0); return metrics->approximate_digit_width; } /* * PangoFontFamily */ GType pango_font_family_get_type (void) { static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (PangoFontFamilyClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, NULL, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoFontFamily), 0, /* n_preallocs */ NULL /* init */ }; object_type = g_type_register_static (G_TYPE_OBJECT, "PangoFontFamily", &object_info, 0); } return object_type; } /** * pango_font_family_get_name: * @family: a #PangoFontFamily * * Gets the name of the family. The name is unique among all * fonts for the font backend and can be used in a #PangoFontDescription * to specify that a face from this family is desired. * * Return value: the name of the family. This string is owned * by the family object and must not be modified or freed. **/ G_CONST_RETURN char * pango_font_family_get_name (PangoFontFamily *family) { g_return_val_if_fail (PANGO_IS_FONT_FAMILY (family), NULL); return PANGO_FONT_FAMILY_GET_CLASS (family)->get_name (family); } /** * pango_font_family_list_faces: * @family: a #PangFontFamily * @faces: location to store an array of pointers to #PangoFontFace * objects, or %NULL. This array should be freed with g_free() * when it is no longer needed. * @n_faces: location to store number of elements in @faces. * * Lists the different font faces that make up @family. The faces * in a family share a common design, but differ in slant, weight, * width and other aspects. **/ void pango_font_family_list_faces (PangoFontFamily *family, PangoFontFace ***faces, int *n_faces) { g_return_if_fail (PANGO_IS_FONT_FAMILY (family)); PANGO_FONT_FAMILY_GET_CLASS (family)->list_faces (family, faces, n_faces); } /* * PangoFontFace */ GType pango_font_face_get_type (void) { static GType object_type = 0; if (!object_type) { static const GTypeInfo object_info = { sizeof (PangoFontFaceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, NULL, /* class_init */ NULL, /* class_finalize */ NULL, /* class_data */ sizeof (PangoFont), 0, /* n_preallocs */ NULL /* init */ }; object_type = g_type_register_static (G_TYPE_OBJECT, "PangoFontFace", &object_info, 0); } return object_type; } /** * pango_font_face_describe: * @face: a #PangoFontFace * * Returns the family, style, variant, weight and stretch of * a #PangoFontFace. The size field of the resulting font description * will be unset. * * Return value: a newly created #PangoFontDescription structure * holding the description of the face. Use pango_font_description_free() * to free the result. **/ PangoFontDescription * pango_font_face_describe (PangoFontFace *face) { g_return_val_if_fail (PANGO_IS_FONT_FACE (face), NULL); return PANGO_FONT_FACE_GET_CLASS (face)->describe (face); } /** * pango_font_face_get_face_name: * @face: a #PangoFontFace. * * Gets a name representing the style of this face among the * different faces in the PangoFontFamily for the face. This * name is unique among all faces in the family and is suitable * for displaying to users. * * Return value: the face name for the face. This string is * owned by the face object and must not be modified or freed. **/ G_CONST_RETURN char * pango_font_face_get_face_name (PangoFontFace *face) { g_return_val_if_fail (PANGO_IS_FONT_FACE (face), NULL); return PANGO_FONT_FACE_GET_CLASS (face)->get_face_name (face); }