From a49e070d24242c0297e6325587c4bc135e13e26c Mon Sep 17 00:00:00 2001 From: Owen Taylor Date: Tue, 18 Sep 2001 20:05:20 +0000 Subject: Up to 0.19. Tue Sep 18 15:47:08 2001 Owen Taylor * configure.in (PANGO_MINOR_VERSION): Up to 0.19. * pango/pango-font.h pango/pango-fontmap.[ch] pango/fonts.c pango/pangoxft-fontmap.c pango/pangoft-fontmap.c pango/pango-context.[ch] pango/pangox-fontmap.c: Add new PangoFontFace and PangoFontFamily object types, and change the font listing API to list faces and families, instead of face names and font descriptions. * pango/pango-font.h pango/fonts.c: Make PangoFontDescription an opaque heap-allocated structure, add accessors and convenience functions. * pango/pango-font.h pango/pango-private.h: Make PangoFontMetrics heap allocated, protect the structure definition with #ifdef PANGO_ENABLE_BACKEND, and add getters for the fields. * pango/pango-attributes.[ch] ( pango_attr_iterator_get_font): instead of providing a base font description and one to fill in, provide a single font description to modify based on the attributes. * pango/pango-attributes.[ch]: Fix PangoAttrFontDesc to have a PangoFontDescription by reference, not by value. * pango/pango-utils.[ch]: make pango_parse_style() and friends take pointers to individual enumerations instead of to a PangoFontDescription structure. * pango/*.c: Fix for the PangoFontDescription and PangoFontMetrics changes. * pango/pango-{break,engine,indic,ot,xft}.h pango/Makefile.am pango/opentype/Makefile.am: Protect portions with PANGO_ENABLE_ENGINE to shrink the public API. * modules/*/Makefile.am: -DPANGO_ENABLE_ENGINE. * pango/{pangox.h,pangox-private.h} modules/basic/basic-x.c: Move pango_x_font_get_unknown_glyph() into public header since it is used from modules. * pango/pango-{context,font,fontmap,modules.utils}.h pango/Makefile.am: Protect portions with PANGO_ENABLE_BACKEND to shrink the public API. * pango/*.h: Use G_BEGIN/END_DECLS * examples/viewer-qt.[cc,h]: Fix for changes to font listing API, PangoFontDescription. * pango/pango-indic.h modules/indic/*: Since we install this header fix it up to Pango conventions, namespece ZERO_WIDTH_JOINER, ZERO_WIDTH_NON_JOINER. * docs/pango-sections.txt: Updated. --- pango/Makefile.am | 2 + pango/fonts.c | 878 ++++++++++++++++++++++++++++++++++++++++++++- pango/opentype/Makefile.am | 1 + pango/pango-attributes.c | 122 +++---- pango/pango-attributes.h | 13 +- pango/pango-break.h | 11 +- pango/pango-context.c | 234 ++++-------- pango/pango-context.h | 25 +- pango/pango-coverage.h | 12 +- pango/pango-engine.h | 12 +- pango/pango-font.h | 231 +++++++++--- pango/pango-fontmap.c | 29 +- pango/pango-fontmap.h | 43 +-- pango/pango-glyph.h | 8 +- pango/pango-indic.h | 19 +- pango/pango-item.h | 8 +- pango/pango-layout.c | 41 ++- pango/pango-layout.h | 8 +- pango/pango-markup.c | 26 +- pango/pango-modules.h | 12 +- pango/pango-ot.h | 11 +- pango/pango-tabs.h | 10 +- pango/pango-types.h | 12 +- pango/pango-utils.c | 68 ++-- pango/pango-utils.h | 36 +- pango/pango.h | 9 - pango/pangoft2-fontmap.c | 808 +++++++++++++++++++++-------------------- pango/pangoft2-private.h | 13 +- pango/pangoft2.c | 39 +- pango/pangoft2.h | 9 +- pango/pangowin32-fontmap.c | 53 ++- pango/pangowin32.c | 15 +- pango/pangowin32.h | 9 +- pango/pangox-fontmap.c | 676 ++++++++++++++++++---------------- pango/pangox-private.h | 13 +- pango/pangox.c | 65 ++-- pango/pangox.h | 14 +- pango/pangoxft-font.c | 34 +- pango/pangoxft-fontmap.c | 481 ++++++++++++++++--------- pango/pangoxft-private.h | 9 +- pango/pangoxft.h | 13 +- 41 files changed, 2606 insertions(+), 1526 deletions(-) (limited to 'pango') diff --git a/pango/Makefile.am b/pango/Makefile.am index 989ae6a7..503d6514 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -18,6 +18,8 @@ SUBDIRS = $(OPENTYPE_SUBDIR) $(FRIBIDI_SUBDIR) DIST_SUBDIRS = mini-fribidi opentype INCLUDES = \ + -DPANGO_ENABLE_BACKEND \ + -DPANGO_ENABLE_ENGINE \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -DLIBDIR=\"$(libdir)\" \ $(X_CFLAGS) \ diff --git a/pango/fonts.c b/pango/fonts.c index 17a0729d..5a2c0ea0 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -29,6 +29,21 @@ #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) { @@ -42,6 +57,502 @@ pango_font_description_get_type (void) 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; + } + 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, or %NULL if the family name is unset. + **/ +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. Returns + * %PANGO_STYLE_NORMAL if the style field is unset. 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. Returns + * %PANGO_VARIANT_NORMAL if the variant field is unset. 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. Returns + * %PANGO_WEIGHT_NORMAL if the weight field is unset. 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. Returns + * %PANGO_STRETCH_NORMAL if the stretch field is unset. 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 is unset. Use + * 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. + **/ +void +pango_font_description_unset_fields (PangoFontDescription *desc, + PangoFontMask to_unset) +{ + g_return_if_fail (desc != NULL); + + /* We reset cleared mask values back to defaults, to avoid + * having to check the mask for getters. + */ + if (to_unset & PANGO_FONT_MASK_FAMILY) + pango_font_description_set_family (desc, NULL); + if (to_unset & PANGO_FONT_MASK_STYLE) + desc->style = PANGO_STYLE_NORMAL; + if (to_unset & PANGO_FONT_MASK_VARIANT) + desc->variant = PANGO_VARIANT_NORMAL; + if (to_unset & PANGO_FONT_MASK_WEIGHT) + desc->weight = PANGO_WEIGHT_NORMAL; + if (to_unset & PANGO_FONT_MASK_STRETCH) + desc->stretch = PANGO_STRETCH_NORMAL; + if (to_unset & PANGO_FONT_MASK_SIZE) + desc->size = 0; + + 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 @@ -63,6 +574,29 @@ pango_font_description_copy (const PangoFontDescription *desc) 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 @@ -82,12 +616,46 @@ pango_font_description_equal (const PangoFontDescription *desc1, g_return_val_if_fail (desc1 != NULL, FALSE); g_return_val_if_fail (desc2 != NULL, FALSE); - return (desc1->style == desc2->style && + 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 && - !g_strcasecmp (desc1->family_name, desc2->family_name)); + (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; } /** @@ -101,7 +669,7 @@ void pango_font_description_free (PangoFontDescription *desc) { if (desc) { - if (desc->family_name) + if (desc->family_name && !desc->static_family) g_free (desc->family_name); g_free (desc); @@ -244,6 +812,11 @@ pango_font_description_from_string (const char *str) 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; @@ -266,6 +839,7 @@ pango_font_description_from_string (const char *str) 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; } } @@ -366,7 +940,7 @@ pango_font_description_to_string (const PangoFontDescription *desc) if (result->len == 0) g_string_append (result, "Normal"); - if (desc->size > 0) + if (desc->mask & PANGO_FONT_MASK_SIZE) { if (result->len > 0 || result->str[result->len -1] != ' ') g_string_append_c (result, ' '); @@ -457,7 +1031,7 @@ pango_font_describe (PangoFont *font) /** * pango_font_get_coverage: * @font: a #PangoFont - * @lang: the language tag + * @language: the language tag * * Compute the coverage map for a given font and language tag. * @@ -531,18 +1105,300 @@ pango_font_get_glyph_extents (PangoFont *font, * @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. - * @metrics: Structure to fill in with the metrics of the 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. **/ - -void +PangoFontMetrics * pango_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { - PANGO_FONT_GET_CLASS (font)->get_metrics (font, language, metrics); + return PANGO_FONT_GET_CLASS (font)->get_metrics (font, language); +} + +/** + * 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 (PangoFont), + 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); } diff --git a/pango/opentype/Makefile.am b/pango/opentype/Makefile.am index f42516df..9f9c9dd5 100644 --- a/pango/opentype/Makefile.am +++ b/pango/opentype/Makefile.am @@ -1,6 +1,7 @@ ## Process this file with automake to produce Makefile.in INCLUDES = \ + -DPANGO_ENABLE_ENGINE \ -DSYSCONFDIR=\"$(sysconfdir)\" \ -DLIBDIR=\"$(libdir)\" \ $(FREETYPE_CFLAGS) \ diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c index 9519c01a..6d6fbf1c 100644 --- a/pango/pango-attributes.c +++ b/pango/pango-attributes.c @@ -505,7 +505,7 @@ pango_attr_font_desc_copy (const PangoAttribute *attr) { const PangoAttrFontDesc *desc_attr = (const PangoAttrFontDesc *)attr; - return pango_attr_font_desc_new (&desc_attr->desc); + return pango_attr_font_desc_new (desc_attr->desc); } static void @@ -513,7 +513,7 @@ pango_attr_font_desc_destroy (PangoAttribute *attr) { PangoAttrFontDesc *desc_attr = (PangoAttrFontDesc *)attr; - g_free (desc_attr->desc.family_name); + pango_font_description_free (desc_attr->desc); g_free (attr); } @@ -524,7 +524,7 @@ pango_attr_font_desc_equal (const PangoAttribute *attr1, const PangoAttrFontDesc *desc_attr1 = (const PangoAttrFontDesc *)attr1; const PangoAttrFontDesc *desc_attr2 = (const PangoAttrFontDesc *)attr2; - return pango_font_description_equal (&desc_attr1->desc, &desc_attr2->desc); + return pango_font_description_equal (desc_attr1->desc, desc_attr2->desc); } /** @@ -549,8 +549,7 @@ pango_attr_font_desc_new (const PangoFontDescription *desc) PangoAttrFontDesc *result = g_new (PangoAttrFontDesc, 1); result->attr.klass = &klass; - result->desc = *desc; - result->desc.family_name = g_strdup (desc->family_name); + result->desc = pango_font_description_copy (desc); return (PangoAttribute *)result; } @@ -1363,15 +1362,13 @@ pango_attr_iterator_get (PangoAttrIterator *iterator, /** * pango_attr_iterator_get_font: * @iterator: a #PangoAttrIterator - * @base: the default values to use for fields not currently overridden. - * @current: a #PangoFontDescription to fill in with the current values. This - * #PangoFontDescription structure cannot be freed with - * pango_font_description_free. The @family member of this structure - * will be filled in with a string that is either shared with - * an attribute in the #PangoAttrList associated with the structure, - * or with @base. If you want to save this value, you should - * allocate it on the stack and then use pango_font_description_copy(). - * @language: if non-%NULl, location to store language tag for item, or %NULL + * @desc: a #PangoFontDescription to fill in with the current values. + * The family name in this structure will be set using + * pango_font_description_set_family_static using values from + * an attribute in the #PangoAttrList associated with the iterator, + * so if you plan to keep it around, you must call: + * pango_font_description_set_family (desc, pango_font_description_get_family (desc)). + * @language: if non-%NULL, location to store language tag for item, or %NULL * if non is found. * @extra_attrs: if non-%NULL, location in which to store a list of non-font * attributes at the the current position; only the highest priority @@ -1383,28 +1380,19 @@ pango_attr_iterator_get (PangoAttrIterator *iterator, **/ void pango_attr_iterator_get_font (PangoAttrIterator *iterator, - PangoFontDescription *base, - PangoFontDescription *current, + PangoFontDescription *desc, PangoLanguage **language, GSList **extra_attrs) { GList *tmp_list1; GSList *tmp_list2; - gboolean have_family = FALSE; - gboolean have_style = FALSE; - gboolean have_variant = FALSE; - gboolean have_weight = FALSE; - gboolean have_stretch = FALSE; - gboolean have_size = FALSE; + PangoFontMask mask = 0; gboolean have_language = FALSE; g_return_if_fail (iterator != NULL); - g_return_if_fail (base != NULL); - g_return_if_fail (current != NULL); + g_return_if_fail (desc != NULL); - *current = *base; - if (language) *language = NULL; @@ -1421,88 +1409,62 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator, { case PANGO_ATTR_FONT_DESC: { - if (!have_family) - { - have_family = TRUE; - current->family_name = ((PangoAttrFontDesc *)attr)->desc.family_name; - } - if (!have_style) - { - have_style = TRUE; - current->style = ((PangoAttrFontDesc *)attr)->desc.style; - } - if (!have_variant) - { - have_variant = TRUE; - current->variant = ((PangoAttrFontDesc *)attr)->desc.variant; - } - if (!have_weight) - { - have_weight = TRUE; - current->weight = ((PangoAttrFontDesc *)attr)->desc.weight; - } - if (!have_stretch) - { - have_stretch = TRUE; - current->stretch = ((PangoAttrFontDesc *)attr)->desc.stretch; - } - if (!have_size) - { - have_size = TRUE; - current->size = ((PangoAttrFontDesc *)attr)->desc.size; - } + PangoFontMask new_mask = pango_font_description_get_set_fields (((PangoAttrFontDesc *)attr)->desc) & ~mask; + pango_font_description_unset_fields (desc, new_mask); + pango_font_description_merge_static (desc, ((PangoAttrFontDesc *)attr)->desc, FALSE); + + break; } - break; - case PANGO_ATTR_FAMILY: - if (!have_family) + if (!(mask & PANGO_ATTR_FAMILY)) { - have_family = TRUE; - current->family_name = ((PangoAttrString *)attr)->value; + mask |= PANGO_ATTR_FAMILY; + pango_font_description_set_family (desc, ((PangoAttrString *)attr)->value); } break; case PANGO_ATTR_STYLE: - if (!have_style) + if (!(mask & PANGO_ATTR_STYLE)) { - have_style = TRUE; - current->style = ((PangoAttrInt *)attr)->value; + mask |= PANGO_ATTR_STYLE; + pango_font_description_set_style (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_VARIANT: - if (!have_variant) + if (!(mask & PANGO_ATTR_VARIANT)) { - have_variant = TRUE; - current->variant = ((PangoAttrInt *)attr)->value; + mask |= PANGO_ATTR_VARIANT; + pango_font_description_set_variant (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_WEIGHT: - if (!have_weight) + if (!(mask & PANGO_ATTR_WEIGHT)) { - have_weight = TRUE; - current->weight = ((PangoAttrInt *)attr)->value; + mask |= PANGO_ATTR_WEIGHT; + pango_font_description_set_weight (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_STRETCH: - if (!have_stretch) + if (!(mask & PANGO_ATTR_STRETCH)) { - have_stretch = TRUE; - current->stretch = ((PangoAttrInt *)attr)->value; + mask |= PANGO_ATTR_STRETCH; + pango_font_description_set_stretch (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_SIZE: - if (!have_size) + if (!(mask & PANGO_ATTR_SIZE)) { - have_size = TRUE; - current->size = ((PangoAttrInt *)attr)->value; + mask |= PANGO_ATTR_SIZE; + pango_font_description_set_size (desc, ((PangoAttrInt *)attr)->value); } break; case PANGO_ATTR_SCALE: - if (!have_size) + if (!(mask & PANGO_ATTR_SIZE)) { - have_size = TRUE; - current->size = ((PangoAttrFloat *)attr)->value * base->size; + mask |= PANGO_ATTR_SIZE; + pango_font_description_set_size (desc, + ((PangoAttrFloat *)attr)->value * pango_font_description_get_size (desc)); } - break; + break; case PANGO_ATTR_LANGUAGE: if (language) { diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h index d863a4af..78669bea 100644 --- a/pango/pango-attributes.h +++ b/pango/pango-attributes.h @@ -25,9 +25,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS /* PangoColor */ @@ -147,7 +145,7 @@ struct _PangoAttrShape struct _PangoAttrFontDesc { PangoAttribute attr; - PangoFontDescription desc; + PangoFontDescription *desc; }; PangoAttrType pango_attr_type_register (const gchar *name); @@ -204,8 +202,7 @@ void pango_attr_iterator_destroy (PangoAttrIterator *iterator PangoAttribute * pango_attr_iterator_get (PangoAttrIterator *iterator, PangoAttrType type); void pango_attr_iterator_get_font (PangoAttrIterator *iterator, - PangoFontDescription *base, - PangoFontDescription *current, + PangoFontDescription *desc, PangoLanguage **language, GSList **extra_attrs); @@ -218,8 +215,6 @@ gboolean pango_parse_markup (const char *markup_text, gunichar *accel_char, GError **error); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_ATTRIBUTES_H__ */ diff --git a/pango/pango-break.h b/pango/pango-break.h index d72ba0da..b8b692f6 100644 --- a/pango/pango-break.h +++ b/pango/pango-break.h @@ -24,9 +24,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #include @@ -87,6 +85,8 @@ void pango_get_log_attrs (const char *text, PangoLanguage *language, PangoLogAttr *log_attrs); +#ifdef PANGO_ENABLE_ENGINE + /* This is the default break algorithm, used if no language * engine overrides it. Normally you should use pango_break() * instead; this function is mostly useful for chaining up @@ -97,9 +97,8 @@ void pango_default_break (const gchar *text, PangoAnalysis *analysis, PangoLogAttr *attrs); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +#endif /* PANGO_ENABLE_ENGINE */ +G_END_DECLS #endif /* __PANGO_BREAK_H__ */ diff --git a/pango/pango-context.c b/pango/pango-context.c index 1bcad534..7f5e078f 100644 --- a/pango/pango-context.c +++ b/pango/pango-context.c @@ -90,20 +90,17 @@ pango_context_get_type (void) static void pango_context_init (PangoContext *context) { - PangoFontDescription desc; - context->base_dir = PANGO_DIRECTION_LTR; context->language = NULL; context->font_maps = NULL; - desc.family_name = "serif"; - desc.style = PANGO_STYLE_NORMAL; - desc.variant = PANGO_VARIANT_NORMAL; - desc.weight = PANGO_WEIGHT_NORMAL; - desc.stretch = PANGO_STRETCH_NORMAL; - desc.size = 12 * PANGO_SCALE; - - context->font_desc = pango_font_description_copy (&desc); + context->font_desc = pango_font_description_new (); + pango_font_description_set_family (context->font_desc, "serif"); + pango_font_description_set_style (context->font_desc, PANGO_STYLE_NORMAL); + pango_font_description_set_variant (context->font_desc, PANGO_VARIANT_NORMAL); + pango_font_description_set_weight (context->font_desc, PANGO_WEIGHT_NORMAL); + pango_font_description_set_stretch (context->font_desc, PANGO_STRETCH_NORMAL); + pango_font_description_set_size (context->font_desc, 12 * PANGO_SCALE); } static void @@ -168,95 +165,10 @@ pango_context_add_font_map (PangoContext *context, context->font_maps = g_slist_append (context->font_maps, font_map); } -/** - * pango_context_list_fonts: - * @context: a #PangoContext - * @family: the family for which to list the fonts, or %NULL - * to list fonts in all families. - * @descs: location to store a pointer to an array of pointers to - * #PangoFontDescription. This array should be freed - * with pango_font_descriptions_free() - * @n_descs: location to store the number of elements in @descs - * - * Lists all fonts in all fontmaps for this context, or all - * fonts in a particular family. - **/ -void -pango_context_list_fonts (PangoContext *context, - const char *family, - PangoFontDescription ***descs, - int *n_descs) -{ - int n_maps; - - g_return_if_fail (context != NULL); - g_return_if_fail (descs == NULL || n_descs != NULL); - - if (n_descs == 0) - return; - - n_maps = g_slist_length (context->font_maps); - - if (n_maps == 0) - { - *n_descs = 0; - if (descs) - *descs = NULL; - return; - } - else if (n_maps == 1) - pango_font_map_list_fonts (context->font_maps->data, family, descs, n_descs); - else - { - /* FIXME: This does not properly suppress duplicate fonts! */ - - PangoFontDescription ***tmp_descs; - int *tmp_n_descs; - int total_n_descs = 0; - GSList *tmp_list; - int i; - - tmp_descs = g_new (PangoFontDescription **, n_maps); - tmp_n_descs = g_new (int, n_maps); - - *n_descs = 0; - - tmp_list = context->font_maps; - for (i = 0; idata, family, &tmp_descs[i], &tmp_n_descs[i]); - *n_descs += tmp_n_descs[i]; - - tmp_list = tmp_list->next; - } - - if (descs) - { - *descs = g_new (PangoFontDescription *, *n_descs); - - total_n_descs = 0; - for (i = 0; ifont_maps->data, families, n_families); else { @@ -317,7 +230,7 @@ pango_context_list_families (PangoContext *context, tmp_list = context->font_maps; while (tmp_list) { - char **tmp_families; + PangoFontFamily **tmp_families; int tmp_n_families; int i; @@ -325,16 +238,16 @@ pango_context_list_families (PangoContext *context, for (i=0; i<*n_families; i++) { + const char *family = pango_font_family_get_name (tmp_families[i]); + if (!g_hash_table_lookup (family_hash, tmp_families[i])) { - char *family = g_strdup (tmp_families[i]); - - g_hash_table_insert (family_hash, family, family); + g_hash_table_insert (family_hash, (char *)family, tmp_families[i]); (*n_families)++; } } - pango_font_map_free_families (tmp_families, tmp_n_families); + g_free (tmp_families); tmp_list = tmp_list->next; } @@ -343,7 +256,7 @@ pango_context_list_families (PangoContext *context, if (families) { - *families = g_new (char *, *n_families); + *families = g_new (PangoFontFamily *, *n_families); info.families = *families; } else @@ -755,24 +668,24 @@ font_set_free (FontSet *font_set) } static void -font_set_load (FontSet *font_set, - PangoContext *context, - PangoLanguage *language, - PangoFontDescription *desc) +font_set_load (FontSet *font_set, + PangoContext *context, + PangoLanguage *language, + const PangoFontDescription *desc) { - PangoFontDescription tmp_desc = *desc; + PangoFontDescription *tmp_desc = pango_font_description_copy_static (desc); char **families; int j; font_set_free (font_set); - families = g_strsplit (desc->family_name, ",", -1); + families = g_strsplit (pango_font_description_get_family (desc), ",", -1); font_set->n_families = 0; for (j=0; families[j] && font_set->n_families < MAX_FAMILIES; j++) { - tmp_desc.family_name = families[j]; - font_set->fonts[font_set->n_families] = pango_context_load_font (context, &tmp_desc); + pango_font_description_set_family_static (tmp_desc, families[j]); + font_set->fonts[font_set->n_families] = pango_context_load_font (context, tmp_desc); if (font_set->fonts[font_set->n_families]) { @@ -782,7 +695,7 @@ font_set_load (FontSet *font_set, } g_strfreev (families); - tmp_desc.family_name = desc->family_name; + pango_font_description_set_family_static (tmp_desc, pango_font_description_get_family (desc)); /* The font description was completely unloadable, try with * family == "Sans" @@ -792,16 +705,14 @@ font_set_load (FontSet *font_set, char *ctmp1, *ctmp2; ctmp1 = pango_font_description_to_string (desc); - tmp_desc.family_name = "Sans"; - ctmp2 = pango_font_description_to_string (&tmp_desc); + pango_font_description_set_family_static (tmp_desc, "Sans"); + ctmp2 = pango_font_description_to_string (tmp_desc); g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2); g_free (ctmp1); g_free (ctmp2); - tmp_desc.family_name = "Sans"; - - font_set->fonts[0] = pango_context_load_font (context, &tmp_desc); + font_set->fonts[0] = pango_context_load_font (context, tmp_desc); if (font_set->fonts[0]) { font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language); @@ -815,18 +726,18 @@ font_set_load (FontSet *font_set, { char *ctmp1, *ctmp2; - ctmp1 = pango_font_description_to_string (&tmp_desc); - tmp_desc.style = PANGO_STYLE_NORMAL; - tmp_desc.weight = PANGO_WEIGHT_NORMAL; - tmp_desc.variant = PANGO_VARIANT_NORMAL; - tmp_desc.stretch = PANGO_STRETCH_NORMAL; - ctmp2 = pango_font_description_to_string (&tmp_desc); + ctmp1 = pango_font_description_to_string (tmp_desc); + pango_font_description_set_style (tmp_desc, PANGO_STYLE_NORMAL); + pango_font_description_set_weight (tmp_desc, PANGO_WEIGHT_NORMAL); + pango_font_description_set_variant (tmp_desc, PANGO_VARIANT_NORMAL); + pango_font_description_set_stretch (tmp_desc, PANGO_STRETCH_NORMAL); + ctmp2 = pango_font_description_to_string (tmp_desc); g_warning ("Couldn't load font \"%s\" falling back to \"%s\"", ctmp1, ctmp2); g_free (ctmp1); g_free (ctmp2); - font_set->fonts[0] = pango_context_load_font (context, &tmp_desc); + font_set->fonts[0] = pango_context_load_font (context, tmp_desc); if (font_set->fonts[0]) { font_set->coverages[0] = pango_font_get_coverage (font_set->fonts[0], language); @@ -841,6 +752,8 @@ font_set_load (FontSet *font_set, g_warning ("All font failbacks failed!!!!"); exit (1); } + + pango_font_description_free (tmp_desc); } static gboolean @@ -880,7 +793,7 @@ add_engines (PangoContext *context, int next_index; GSList *extra_attrs = NULL; PangoMap *lang_map = NULL; - PangoFontDescription current_desc = { 0 }; + PangoFontDescription *current_desc = NULL; FontSet current_fonts = FONT_SET_INITIALIZER; PangoAttrIterator *iterator; gboolean first_iteration = TRUE; @@ -905,7 +818,7 @@ add_engines (PangoContext *context, if (first_iteration || pos - text == next_index) { PangoLanguage *next_language; - PangoFontDescription next_desc; + PangoFontDescription *next_desc = pango_font_description_copy_static (context->font_desc); first_iteration = FALSE; @@ -918,8 +831,7 @@ add_engines (PangoContext *context, pango_attr_iterator_range (iterator, NULL, &next_index); } - pango_attr_iterator_get_font (iterator, context->font_desc, - &next_desc, &next_language, &extra_attrs); + pango_attr_iterator_get_font (iterator, next_desc, &next_language, &extra_attrs); if (!next_language) next_language = context->language; @@ -941,13 +853,15 @@ add_engines (PangoContext *context, engine_type_id, render_type_id); } - if (i == 0 || - !pango_font_description_equal (¤t_desc, &next_desc)) + if (i == 0 || !pango_font_description_equal (current_desc, next_desc)) { + pango_font_description_free (current_desc); current_desc = next_desc; - font_set_load (¤t_fonts, context, language, ¤t_desc); + font_set_load (¤t_fonts, context, language, current_desc); } + else + pango_font_description_free (next_desc); } wc = g_utf8_get_char (pos); @@ -978,6 +892,8 @@ add_engines (PangoContext *context, g_assert (pos - text == start_index + length); + if (current_desc) + pango_font_description_free (current_desc); font_set_free (¤t_fonts); if (iterator != cached_iter) @@ -991,7 +907,6 @@ add_engines (PangoContext *context, * @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. - * @metrics: Structure to fill in with the metrics of the font * * Get overall metric information for a font particular font * description. Since the metrics may be substantially different for @@ -1005,66 +920,71 @@ add_engines (PangoContext *context, * would be used to render the string, then the returned fonts would * be a composite of the metrics for the fonts loaded for the * individual families. + * + * Returns: a #PangoMetrics object. The caller must call pango_font_metrics_unref() + * when finished using the object. **/ -void +PangoFontMetrics * pango_context_get_metrics (PangoContext *context, const PangoFontDescription *desc, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { FontSet current_fonts = FONT_SET_INITIALIZER; - PangoFontMetrics raw_metrics[MAX_FAMILIES]; - gboolean have_metrics[MAX_FAMILIES]; - PangoFontDescription tmp_desc = *desc; + PangoFontMetrics *raw_metrics[MAX_FAMILIES]; + PangoFontMetrics *metrics; const char *sample_str; const char *p; int i; - g_return_if_fail (PANGO_IS_CONTEXT (context)); - g_return_if_fail (desc != NULL); - g_return_if_fail (metrics != NULL); + g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL); + g_return_val_if_fail (desc != NULL, NULL); sample_str = pango_language_get_sample_string (language); - font_set_load (¤t_fonts, context, language, &tmp_desc); + font_set_load (¤t_fonts, context, language, desc); - for (i=0; i < MAX_FAMILIES; i++) - have_metrics[i] = FALSE; - if (current_fonts.n_families == 1) - pango_font_get_metrics (current_fonts.fonts[0], language, metrics); + metrics = pango_font_get_metrics (current_fonts.fonts[0], language); else { int count = 0; + metrics = pango_font_metrics_new (); + + for (i=0; i < MAX_FAMILIES; i++) + raw_metrics[i] = NULL; + p = sample_str; while (*p) { gunichar wc = g_utf8_get_char (p); int index = font_set_get_font (¤t_fonts, wc); - if (!have_metrics[index]) - { - pango_font_get_metrics (current_fonts.fonts[index], language, &raw_metrics[index]); - have_metrics[index] = TRUE; - } + if (!raw_metrics[index]) + raw_metrics[index] = pango_font_get_metrics (current_fonts.fonts[index], language); if (count == 0) - *metrics = raw_metrics[index]; + *metrics = *raw_metrics[index]; else { - metrics->ascent = MAX (metrics->ascent, raw_metrics[index].ascent); - metrics->descent = MAX (metrics->descent, raw_metrics[index].descent); - metrics->approximate_char_width += raw_metrics[index].approximate_char_width; - metrics->approximate_digit_width += raw_metrics[index].approximate_digit_width; + metrics->ascent = MAX (metrics->ascent, raw_metrics[index]->ascent); + metrics->descent = MAX (metrics->descent, raw_metrics[index]->descent); + metrics->approximate_char_width += raw_metrics[index]->approximate_char_width; + metrics->approximate_digit_width += raw_metrics[index]->approximate_digit_width; } p = g_utf8_next_char (p); count++; } + for (i=0; i < MAX_FAMILIES; i++) + if (raw_metrics[i]) + pango_font_metrics_unref (raw_metrics[i]); + metrics->approximate_char_width /= count; metrics->approximate_digit_width /= count; } font_set_free (¤t_fonts); + + return metrics; } diff --git a/pango/pango-context.h b/pango/pango-context.h index 471328eb..b9b6be24 100644 --- a/pango/pango-context.h +++ b/pango/pango-context.h @@ -26,9 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS /* Sort of like a GC - application set information about how * to handle scripts @@ -49,23 +47,22 @@ typedef struct _PangoContextClass PangoContextClass; */ GType pango_context_get_type (void) G_GNUC_CONST; + +#ifdef PANGO_ENABLE_BACKEND PangoContext *pango_context_new (void); void pango_context_add_font_map (PangoContext *context, PangoFontMap *font_map); -void pango_context_list_fonts (PangoContext *context, - const char *family, - PangoFontDescription ***descs, - int *n_descs); +#endif /* PANGO_ENABLE_BACKEND */ + void pango_context_list_families (PangoContext *context, - gchar ***families, + PangoFontFamily ***families, int *n_families); PangoFont * pango_context_load_font (PangoContext *context, const PangoFontDescription *desc); -void pango_context_get_metrics (PangoContext *context, - const PangoFontDescription *desc, - PangoLanguage *language, - PangoFontMetrics *metrics); +PangoFontMetrics *pango_context_get_metrics (PangoContext *context, + const PangoFontDescription *desc, + PangoLanguage *language); void pango_context_set_font_description (PangoContext *context, const PangoFontDescription *desc); @@ -89,8 +86,6 @@ GList *pango_itemize (PangoContext *context, PangoAttrIterator *cached_iter); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_CONTEXT_H__ */ diff --git a/pango/pango-coverage.h b/pango/pango-coverage.h index a10eb4cb..0ebe4fb6 100644 --- a/pango/pango-coverage.h +++ b/pango/pango-coverage.h @@ -24,9 +24,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef struct _PangoCoverage PangoCoverage; @@ -55,12 +53,6 @@ void pango_coverage_to_bytes (PangoCoverage *coverage, PangoCoverage *pango_coverage_from_bytes (guchar *bytes, int n_bytes); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_COVERAGE_H__ */ - - - - diff --git a/pango/pango-engine.h b/pango/pango-engine.h index 447e0ee9..d19367ee 100644 --- a/pango/pango-engine.h +++ b/pango/pango-engine.h @@ -27,9 +27,9 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS + +#ifdef PANGO_ENABLE_ENGINE /* Module API */ @@ -94,8 +94,8 @@ PangoEngine *script_engine_load (const char *id); void script_engine_unload (PangoEngine *engine); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +#endif /* PANGO_ENABLE_ENGINE */ + +G_END_DECLS #endif /* __PANGO_ENGINE_H__ */ diff --git a/pango/pango-font.h b/pango/pango-font.h index b59038f2..e6d1cc0d 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -22,15 +22,13 @@ #ifndef __PANGO_FONT_H__ #define __PANGO_FONT_H__ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - #include #include #include +G_BEGIN_DECLS + typedef struct _PangoFontDescription PangoFontDescription; typedef struct _PangoFontMetrics PangoFontMetrics; @@ -74,6 +72,14 @@ typedef enum { PANGO_STRETCH_ULTRA_EXPANDED } PangoStretch; +typedef enum { + PANGO_FONT_MASK_FAMILY = 1 << 0, + PANGO_FONT_MASK_STYLE = 1 << 1, + PANGO_FONT_MASK_VARIANT = 1 << 2, + PANGO_FONT_MASK_WEIGHT = 1 << 3, + PANGO_FONT_MASK_STRETCH = 1 << 4, + PANGO_FONT_MASK_SIZE = 1 << 5 +} PangoFontMask; /* CSS scale factors (1.2 factor between each size) */ #define PANGO_SCALE_XX_SMALL ((double)0.5787037037037) @@ -84,53 +90,199 @@ typedef enum { #define PANGO_SCALE_X_LARGE ((double)1.4399999999999) #define PANGO_SCALE_XX_LARGE ((double)1.728) -struct _PangoFontDescription -{ - char *family_name; - - PangoStyle style; - PangoVariant variant; - PangoWeight weight; - PangoStretch stretch; - - int size; -}; - -struct _PangoFontMetrics -{ - int ascent; - int descent; - int approximate_char_width; - int approximate_digit_width; -}; +/* + * PangoFontDescription + */ #define PANGO_TYPE_FONT_DESCRIPTION (pango_font_description_get_type ()) GType pango_font_description_get_type (void); +PangoFontDescription *pango_font_description_new (void); PangoFontDescription *pango_font_description_copy (const PangoFontDescription *desc); +PangoFontDescription *pango_font_description_copy_static (const PangoFontDescription *desc); +guint pango_font_description_hash (const PangoFontDescription *desc); gboolean pango_font_description_equal (const PangoFontDescription *desc1, const PangoFontDescription *desc2); void pango_font_description_free (PangoFontDescription *desc); void pango_font_descriptions_free (PangoFontDescription **descs, int n_descs); +void pango_font_description_set_family (PangoFontDescription *desc, + const char *family); +void pango_font_description_set_family_static (PangoFontDescription *desc, + const char *family); +G_CONST_RETURN char *pango_font_description_get_family (const PangoFontDescription *desc); +void pango_font_description_set_style (PangoFontDescription *desc, + PangoStyle style); +PangoStyle pango_font_description_get_style (const PangoFontDescription *desc); +void pango_font_description_set_variant (PangoFontDescription *desc, + PangoVariant variant); +PangoVariant pango_font_description_get_variant (const PangoFontDescription *desc); +void pango_font_description_set_weight (PangoFontDescription *desc, + PangoWeight weight); +PangoWeight pango_font_description_get_weight (const PangoFontDescription *desc); +void pango_font_description_set_stretch (PangoFontDescription *desc, + PangoStretch stretch); +PangoStretch pango_font_description_get_stretch (const PangoFontDescription *desc); +void pango_font_description_set_size (PangoFontDescription *desc, + gint size); +gint pango_font_description_get_size (const PangoFontDescription *desc); + +PangoFontMask pango_font_description_get_set_fields (const PangoFontDescription *desc); +void pango_font_description_unset_fields (PangoFontDescription *desc, + PangoFontMask to_unset); + +void pango_font_description_merge (PangoFontDescription *desc, + const PangoFontDescription *desc_to_merge, + gboolean replace_existing); +void pango_font_description_merge_static (PangoFontDescription *desc, + const PangoFontDescription *desc_to_merge, + gboolean replace_existing); + +gboolean pango_font_description_better_match (const PangoFontDescription *desc, + const PangoFontDescription *old_match, + const PangoFontDescription *new_match); + PangoFontDescription *pango_font_description_from_string (const char *str); char * pango_font_description_to_string (const PangoFontDescription *desc); char * pango_font_description_to_filename (const PangoFontDescription *desc); +/* + * PangoFontMetrics + */ +PangoFontMetrics *pango_font_metrics_ref (PangoFontMetrics *metrics); +void pango_font_metrics_unref (PangoFontMetrics *metrics); +int pango_font_metrics_get_ascent (PangoFontMetrics *metrics); +int pango_font_metrics_get_descent (PangoFontMetrics *metrics); +int pango_font_metrics_get_approximate_char_width (PangoFontMetrics *metrics); +int pango_font_metrics_get_approximate_digit_width (PangoFontMetrics *metrics); + +#ifdef PANGO_ENABLE_BACKEND + +PangoFontMetrics *pango_font_metrics_new (void); + +struct _PangoFontMetrics +{ + guint ref_count; + + int ascent; + int descent; + int approximate_char_width; + int approximate_digit_width; +}; + +#endif /* PANGO_ENABLE_BACKEND */ + +/* + * PangoFontFamily + */ + +#define PANGO_TYPE_FONT_FAMILY (pango_font_family_get_type ()) +#define PANGO_FONT_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_FAMILY, PangoFontFamily)) +#define PANGO_IS_FONT_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_FAMILY)) + +typedef struct _PangoFontFamily PangoFontFamily; +typedef struct _PangoFontFace PangoFontFace; + +GType pango_font_family_get_type (void) G_GNUC_CONST; + +void pango_font_family_list_faces (PangoFontFamily *family, + PangoFontFace ***faces, + int *n_faces); +G_CONST_RETURN char *pango_font_family_get_name (PangoFontFamily *family); + +#ifdef PANGO_ENABLE_BACKEND + +#define PANGO_FONT_FAMILY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_FAMILY, PangoFontFamilyClass)) +#define PANGO_IS_FONT_FAMILY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONT_FAMILY)) +#define PANGO_FONT_FAMILY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_FAMILY, PangoFontFamilyClass)) + +typedef struct _PangoFontFamilyClass PangoFontFamilyClass; + +struct _PangoFontFamily +{ + GObject parent_instance; +}; + +struct _PangoFontFamilyClass +{ + GObjectClass parent_class; + + void (*list_faces) (PangoFontFamily *family, + PangoFontFace ***faces, + int *n_faces); + const char * (*get_name) (PangoFontFamily *family); +}; + +#endif /* PANGO_ENABLE_BACKEND */ + +/* + * PangoFontFace + */ + +#define PANGO_TYPE_FONT_FACE (pango_font_face_get_type ()) +#define PANGO_FONT_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_FACE, PangoFontFace)) +#define PANGO_IS_FONT_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_FACE)) + +GType pango_font_face_get_type (void) G_GNUC_CONST; + +PangoFontDescription *pango_font_face_describe (PangoFontFace *face); +G_CONST_RETURN char *pango_font_face_get_face_name (PangoFontFace *face); + +#ifdef PANGO_ENABLE_BACKEND + +#define PANGO_FONT_FACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_FACE, PangoFontFaceClass)) +#define PANGO_IS_FONT_FACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONT_FACE)) +#define PANGO_FONT_FACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_FACE, PangoFontFaceClass)) + +typedef struct _PangoFontFaceClass PangoFontFaceClass; + +struct _PangoFontFace +{ + GObject parent_instance; +}; + +struct _PangoFontFaceClass +{ + GObjectClass parent_class; + + const char * (*get_face_name) (PangoFontFace *face); + PangoFontDescription * (*describe) (PangoFontFace *face); +}; -/* Logical fonts - */ +#endif /* PANGO_ENABLE_BACKEND */ -typedef struct _PangoFontClass PangoFontClass; +/* + * PangoFont + */ #define PANGO_TYPE_FONT (pango_font_get_type ()) #define PANGO_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT, PangoFont)) -#define PANGO_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT, PangoFontClass)) #define PANGO_IS_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT)) + +GType pango_font_get_type (void) G_GNUC_CONST; + +PangoFontDescription *pango_font_describe (PangoFont *font); +PangoCoverage * pango_font_get_coverage (PangoFont *font, + PangoLanguage *language); +PangoEngineShape * pango_font_find_shaper (PangoFont *font, + PangoLanguage *language, + guint32 ch); +PangoFontMetrics * pango_font_get_metrics (PangoFont *font, + PangoLanguage *language); +void pango_font_get_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); + +#ifdef PANGO_ENABLE_BACKEND + +#define PANGO_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT, PangoFontClass)) #define PANGO_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONT)) #define PANGO_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT, PangoFontClass)) +typedef struct _PangoFontClass PangoFontClass; + struct _PangoFont { GObject parent_instance; @@ -150,29 +302,12 @@ struct _PangoFontClass PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); - void (*get_metrics) (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics); + PangoFontMetrics * (*get_metrics) (PangoFont *font, + PangoLanguage *language); }; -GType pango_font_get_type (void) G_GNUC_CONST; - -PangoFontDescription *pango_font_describe (PangoFont *font); -PangoCoverage * pango_font_get_coverage (PangoFont *font, - PangoLanguage *language); -PangoEngineShape * pango_font_find_shaper (PangoFont *font, - PangoLanguage *language, - guint32 ch); -void pango_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics); -void pango_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect); +#endif /* PANGO_ENABLE_BACKEND */ -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_FONT_H__ */ diff --git a/pango/pango-fontmap.c b/pango/pango-fontmap.c index 61e8553f..a7b5b5f2 100644 --- a/pango/pango-fontmap.c +++ b/pango/pango-fontmap.c @@ -67,29 +67,6 @@ pango_font_map_load_font (PangoFontMap *fontmap, return PANGO_FONT_MAP_GET_CLASS (fontmap)->load_font (fontmap, desc); } -/** - * pango_font_map_list_fonts: - * @fontmap: a #PangoFontMap - * @family: the family for which to list the fonts, or %NULL - * to list fonts in all families. - * @descs: location to store a pointer to an array of pointers to - * #PangoFontDescription. This array should be freed - * with pango_font_descriptions_free(). - * @n_descs: location to store the number of elements in @descs - * - * List all fonts in a fontmap, or the fonts in a particular family. - **/ -void -pango_font_map_list_fonts (PangoFontMap *fontmap, - const char *family, - PangoFontDescription ***descs, - int *n_descs) -{ - g_return_if_fail (fontmap != NULL); - - PANGO_FONT_MAP_GET_CLASS (fontmap)->list_fonts (fontmap, family, descs, n_descs); -} - /** * pango_font_map_list_families: * @fontmap: a #PangoFontMap @@ -100,9 +77,9 @@ pango_font_map_list_fonts (PangoFontMap *fontmap, * List all families for a fontmap. **/ void -pango_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, - int *n_families) +pango_font_map_list_families (PangoFontMap *fontmap, + PangoFontFamily ***families, + int *n_families) { g_return_if_fail (fontmap != NULL); diff --git a/pango/pango-fontmap.h b/pango/pango-fontmap.h index 9434f89c..eaf960f5 100644 --- a/pango/pango-fontmap.h +++ b/pango/pango-fontmap.h @@ -23,20 +23,28 @@ #define __PANGO_FONTMAP_H__ #include -#include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define PANGO_TYPE_FONT_MAP (pango_font_map_get_type ()) #define PANGO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FONT_MAP, PangoFontMap)) -#define PANGO_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_MAP, PangoFontMapClass)) #define PANGO_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FONT_MAP)) + +typedef struct _PangoFontMap PangoFontMap; + +GType pango_font_map_get_type (void) G_GNUC_CONST; +PangoFont *pango_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *desc); +void pango_font_map_list_families (PangoFontMap *fontmap, + PangoFontFamily ***families, + int *n_families); + +#ifdef PANGO_ENABLE_BACKEND + +#define PANGO_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_MAP, PangoFontMapClass)) #define PANGO_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FONT_MAP)) #define PANGO_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FONT_MAP, PangoFontMapClass)) -typedef struct _PangoFontMap PangoFontMap; typedef struct _PangoFontMapClass PangoFontMapClass; struct _PangoFontMap @@ -50,30 +58,13 @@ struct _PangoFontMapClass PangoFont *(*load_font) (PangoFontMap *fontmap, const PangoFontDescription *desc); - void (*list_fonts) (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); void (*list_families) (PangoFontMap *fontmap, - gchar ***families, + PangoFontFamily ***families, int *n_families); }; -GType pango_font_map_get_type (void) G_GNUC_CONST; -PangoFont *pango_font_map_load_font (PangoFontMap *fontmap, - const PangoFontDescription *desc); -void pango_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); -void pango_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, - int *n_families); -void pango_font_map_free_families (gchar **families, - int n_families); +#endif /* PANGO_ENABLE_BACKEND */ -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_FONTMAP_H__ */ diff --git a/pango/pango-glyph.h b/pango/pango-glyph.h index f30a3c4f..16db8f8a 100644 --- a/pango/pango-glyph.h +++ b/pango/pango-glyph.h @@ -25,9 +25,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef struct _PangoGlyphGeometry PangoGlyphGeometry; typedef struct _PangoGlyphVisAttr PangoGlyphVisAttr; @@ -131,8 +129,6 @@ void pango_shape (const gchar *text, GList *pango_reorder_items (GList *logical_items); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_GLYPH_H__ */ diff --git a/pango/pango-indic.h b/pango/pango-indic.h index 35b7fb4b..daab3cb4 100644 --- a/pango/pango-indic.h +++ b/pango/pango-indic.h @@ -28,11 +28,17 @@ * or like living dangerously. */ -#ifndef __PANGO_PANGO_INDIC_H__ -#define __PANGO_PANGO_INDIC_H__ +#ifndef __PANGO_INDIC_H__ +#define __PANGO_INDIC_H__ -#define ZERO_WIDTH_NON_JOINER 0x200c -#define ZERO_WIDTH_JOINER 0x200d +#include + +G_BEGIN_DECLS + +#ifdef PANGO_ENABLE_ENGINE + +#define PANGO_ZERO_WIDTH_NON_JOINER 0x200c +#define PANGO_ZERO_WIDTH_JOINER 0x200d typedef struct _PangoIndicScript PangoIndicScript; @@ -76,5 +82,8 @@ void pango_indic_split_out_characters (PangoIndicScript *script, int *n_glyph, PangoGlyphString *glyphs); +#endif /* PANGO_ENABLE_ENGINE */ + +G_END_DECLS -#endif +#endif /* __PANGO_INDIC_H */ diff --git a/pango/pango-item.h b/pango/pango-item.h index 59e67945..c16368a8 100644 --- a/pango/pango-item.h +++ b/pango/pango-item.h @@ -25,9 +25,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef struct _PangoAnalysis PangoAnalysis; typedef struct _PangoItem PangoItem; @@ -57,8 +55,6 @@ PangoItem *pango_item_split (PangoItem *orig, int split_index, int split_offset); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_ITEM_H__ */ diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 8db262b0..194e54d4 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -2251,18 +2251,19 @@ ensure_tab_width (PangoLayout *layout) PangoAttrList *layout_attrs; PangoAttrList *tmp_attrs; PangoAttrIterator *iter; - PangoFontDescription font_desc; + PangoFontDescription *font_desc = pango_font_description_copy_static (pango_context_get_font_description (layout->context)); PangoLanguage *language; int i; layout_attrs = pango_layout_get_effective_attributes (layout); iter = pango_attr_list_get_iterator (layout_attrs); - pango_attr_iterator_get_font (iter, pango_context_get_font_description (layout->context), - &font_desc, &language, NULL); + pango_attr_iterator_get_font (iter, font_desc, &language, NULL); tmp_attrs = pango_attr_list_new (); - attr = pango_attr_font_desc_new (&font_desc); + attr = pango_attr_font_desc_new (font_desc); + pango_font_description_free (font_desc); + attr->start_index = 0; attr->end_index = 1; pango_attr_list_insert_before (tmp_attrs, attr); @@ -3293,9 +3294,9 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, char *line_start; int index; PangoLayout *layout = line->layout; - PangoFontDescription font_desc; PangoFont *font; - PangoFontMetrics metrics; + PangoFontDescription *font_desc = NULL; + gboolean free_font_desc = FALSE; pango_layout_line_get_range (line, &line_start, NULL); index = line_start - layout->text; @@ -3319,12 +3320,15 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, base_font_desc = layout->font_desc; else base_font_desc = pango_context_get_font_description (layout->context); + + font_desc = pango_font_description_copy_static (base_font_desc); + free_font_desc = TRUE; pango_attr_iterator_get_font (iter, - base_font_desc, - &font_desc, + font_desc, NULL, NULL); + break; } @@ -3336,28 +3340,33 @@ pango_layout_line_get_empty_extents (PangoLayoutLine *line, else { if (layout->font_desc) - font_desc = *layout->font_desc; + font_desc = layout->font_desc; else - font_desc = *pango_context_get_font_description (layout->context); + font_desc = pango_context_get_font_description (layout->context); } - font = pango_context_load_font (layout->context, &font_desc); + font = pango_context_load_font (layout->context, font_desc); if (font) { - pango_font_get_metrics (font, - pango_context_get_language (layout->context), - &metrics); + PangoFontMetrics *metrics; - logical_rect->y = - metrics.ascent; - logical_rect->height = metrics.ascent + metrics.descent; + metrics = pango_font_get_metrics (font, + pango_context_get_language (layout->context)); + + logical_rect->y = - pango_font_metrics_get_ascent (metrics); + logical_rect->height = - logical_rect->y + pango_font_metrics_get_descent (metrics); g_object_unref (G_OBJECT (font)); + pango_font_metrics_unref (metrics); } else { logical_rect->y = 0; logical_rect->height = 0; } + + if (free_font_desc) + pango_font_description_free (font_desc); logical_rect->x = 0; logical_rect->width = 0; diff --git a/pango/pango-layout.h b/pango/pango-layout.h index 85b00e42..fc43ece2 100644 --- a/pango/pango-layout.h +++ b/pango/pango-layout.h @@ -27,9 +27,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef struct _PangoLayout PangoLayout; typedef struct _PangoLayoutClass PangoLayoutClass; @@ -230,9 +228,7 @@ void pango_layout_iter_get_layout_extents (PangoLayoutIter *iter, PangoRectangle *logical_rect); int pango_layout_iter_get_baseline (PangoLayoutIter *iter); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_LAYOUT_H__ */ diff --git a/pango/pango-markup.c b/pango/pango-markup.c index 041eaa3d..0ce40c68 100644 --- a/pango/pango-markup.c +++ b/pango/pango-markup.c @@ -943,7 +943,7 @@ span_parse_func (MarkupData *md, if (parsed) { add_attribute (tag, pango_attr_font_desc_new (parsed)); - open_tag_set_absolute_font_size (tag, parsed->size); + open_tag_set_absolute_font_size (tag, pango_font_description_get_size (parsed)); pango_font_description_free (parsed); } } @@ -1004,10 +1004,10 @@ span_parse_func (MarkupData *md, if (style) { - PangoFontDescription desc; + PangoStyle pango_style; - if (pango_parse_style (style, &desc, FALSE)) - add_attribute (tag, pango_attr_style_new (desc.style)); + if (pango_parse_style (style, &pango_style, FALSE)) + add_attribute (tag, pango_attr_style_new (pango_style)); else { g_set_error (error, @@ -1023,11 +1023,11 @@ span_parse_func (MarkupData *md, if (weight) { - PangoFontDescription desc; + PangoWeight pango_weight; - if (pango_parse_weight (weight, &desc, FALSE)) + if (pango_parse_weight (weight, &pango_weight, FALSE)) add_attribute (tag, - pango_attr_weight_new (desc.weight)); + pango_attr_weight_new (pango_weight)); else { g_set_error (error, @@ -1043,10 +1043,10 @@ span_parse_func (MarkupData *md, if (variant) { - PangoFontDescription desc; + PangoVariant pango_variant; - if (pango_parse_variant (variant, &desc, FALSE)) - add_attribute (tag, pango_attr_variant_new (desc.variant)); + if (pango_parse_variant (variant, &pango_variant, FALSE)) + add_attribute (tag, pango_attr_variant_new (pango_variant)); else { g_set_error (error, @@ -1062,10 +1062,10 @@ span_parse_func (MarkupData *md, if (stretch) { - PangoFontDescription desc; + PangoStretch pango_stretch; - if (pango_parse_stretch (stretch, &desc, FALSE)) - add_attribute (tag, pango_attr_stretch_new (desc.stretch)); + if (pango_parse_stretch (stretch, &pango_stretch, FALSE)) + add_attribute (tag, pango_attr_stretch_new (pango_stretch)); else { g_set_error (error, diff --git a/pango/pango-modules.h b/pango/pango-modules.h index 28863083..c0c65301 100644 --- a/pango/pango-modules.h +++ b/pango/pango-modules.h @@ -24,9 +24,9 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS + +#ifdef PANGO_ENABLE_BACKEND typedef struct _PangoMap PangoMap; typedef struct _PangoMapEntry PangoMapEntry; @@ -55,8 +55,8 @@ PangoEngine * pango_map_get_engine (PangoMap *map, guint32 wc); void pango_module_register (PangoIncludedModule *module); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +#endif /* PANGO_ENABLE_BACKEND */ + +G_END_DECLS #endif /* __PANGO_MODULES_H__ */ diff --git a/pango/pango-ot.h b/pango/pango-ot.h index 85788cc6..ce88eb71 100644 --- a/pango/pango-ot.h +++ b/pango/pango-ot.h @@ -25,9 +25,9 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS + +#ifdef PANGO_ENABLE_ENGINE typedef guint32 PangoOTTag; @@ -122,9 +122,8 @@ void pango_ot_ruleset_shape (PangoOTRuleset *ruleset, PangoGlyphString *glyphs, gulong *properties); -#ifdef __cplusplus -} -#endif /* __cplusplus */ +#endif /* PANGO_ENABLE_ENGINE */ +G_END_DECLS #endif /* __PANGO_OT_H__ */ diff --git a/pango/pango-tabs.h b/pango/pango-tabs.h index 26adf499..f60949e8 100644 --- a/pango/pango-tabs.h +++ b/pango/pango-tabs.h @@ -24,9 +24,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS typedef struct _PangoTabArray PangoTabArray; @@ -73,10 +71,6 @@ void pango_tab_array_get_tabs (PangoTabArray *tab_array, gboolean pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array); - - -#ifdef __cplusplus -} -#endif /* __cplusplus */ +G_END_DECLS #endif /* __PANGO_TABS_H__ */ diff --git a/pango/pango-types.h b/pango/pango-types.h index d273b852..993402aa 100644 --- a/pango/pango-types.h +++ b/pango/pango-types.h @@ -25,7 +25,8 @@ #include #include -typedef struct _PangoLangRange PangoLangRange; +G_BEGIN_DECLS + typedef struct _PangoLogAttr PangoLogAttr; typedef struct _PangoEngineLang PangoEngineLang; @@ -84,14 +85,7 @@ PangoLanguage *pango_language_from_string (const char *language); gboolean pango_language_matches (PangoLanguage *language, const char *range_list); -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __PANGO_TYPES_H__ */ diff --git a/pango/pango-utils.c b/pango/pango-utils.c index b27fe4a3..ecde5310 100644 --- a/pango/pango-utils.c +++ b/pango/pango-utils.c @@ -648,9 +648,9 @@ pango_get_lib_subdirectory (void) } gboolean -pango_parse_style (const char *str, - PangoFontDescription *desc, - gboolean warn) +pango_parse_style (const char *str, + PangoStyle *style, + gboolean warn) { if (*str == '\0') return FALSE; @@ -661,21 +661,21 @@ pango_parse_style (const char *str, case 'N': if (g_strcasecmp (str, "normal") == 0) { - desc->style = PANGO_STYLE_NORMAL; + *style = PANGO_STYLE_NORMAL; return TRUE; } break; case 'i': if (g_strcasecmp (str, "italic") == 0) { - desc->style = PANGO_STYLE_ITALIC; + *style = PANGO_STYLE_ITALIC; return TRUE; } break; case 'o': if (g_strcasecmp (str, "oblique") == 0) { - desc->style = PANGO_STYLE_OBLIQUE; + *style = PANGO_STYLE_OBLIQUE; return TRUE; } break; @@ -687,9 +687,9 @@ pango_parse_style (const char *str, } gboolean -pango_parse_variant (const char *str, - PangoFontDescription *desc, - gboolean warn) +pango_parse_variant (const char *str, + PangoVariant *variant, + gboolean warn) { if (*str == '\0') return FALSE; @@ -700,7 +700,7 @@ pango_parse_variant (const char *str, case 'N': if (g_strcasecmp (str, "normal") == 0) { - desc->variant = PANGO_VARIANT_NORMAL; + *variant = PANGO_VARIANT_NORMAL; return TRUE; } break; @@ -709,7 +709,7 @@ pango_parse_variant (const char *str, if (g_strcasecmp (str, "small_caps") == 0 || g_strcasecmp (str, "smallcaps") == 0) { - desc->variant = PANGO_VARIANT_SMALL_CAPS; + *variant = PANGO_VARIANT_SMALL_CAPS; return TRUE; } break; @@ -721,9 +721,9 @@ pango_parse_variant (const char *str, } gboolean -pango_parse_weight (const char *str, - PangoFontDescription *desc, - gboolean warn) +pango_parse_weight (const char *str, + PangoWeight *weight, + gboolean warn) { if (*str == '\0') return FALSE; @@ -734,7 +734,7 @@ pango_parse_weight (const char *str, case 'B': if (g_strcasecmp (str, "bold") == 0) { - desc->weight = PANGO_WEIGHT_BOLD; + *weight = PANGO_WEIGHT_BOLD; return TRUE; } break; @@ -742,7 +742,7 @@ pango_parse_weight (const char *str, case 'H': if (g_strcasecmp (str, "heavy") == 0) { - desc->weight = PANGO_WEIGHT_HEAVY; + *weight = PANGO_WEIGHT_HEAVY; return TRUE; } break; @@ -750,7 +750,7 @@ pango_parse_weight (const char *str, case 'L': if (g_strcasecmp (str, "light") == 0) { - desc->weight = PANGO_WEIGHT_LIGHT; + *weight = PANGO_WEIGHT_LIGHT; return TRUE; } break; @@ -758,7 +758,7 @@ pango_parse_weight (const char *str, case 'N': if (g_strcasecmp (str, "normal") == 0) { - desc->weight = PANGO_WEIGHT_NORMAL; + *weight = PANGO_WEIGHT_NORMAL; return TRUE; } break; @@ -766,12 +766,12 @@ pango_parse_weight (const char *str, case 'U': if (g_strcasecmp (str, "ultralight") == 0) { - desc->weight = PANGO_WEIGHT_ULTRALIGHT; + *weight = PANGO_WEIGHT_ULTRALIGHT; return TRUE; } else if (g_strcasecmp (str, "ultrabold") == 0) { - desc->weight = PANGO_WEIGHT_ULTRABOLD; + *weight = PANGO_WEIGHT_ULTRABOLD; return TRUE; } break; @@ -788,7 +788,7 @@ pango_parse_weight (const char *str, { char *end; - desc->weight = strtol (str, &end, 0); + *weight = strtol (str, &end, 0); if (*end != '\0') { if (warn) @@ -805,9 +805,9 @@ pango_parse_weight (const char *str, } gboolean -pango_parse_stretch (const char *str, - PangoFontDescription *desc, - gboolean warn) +pango_parse_stretch (const char *str, + PangoStretch *stretch, + gboolean warn) { if (*str == '\0') return FALSE; @@ -818,7 +818,7 @@ pango_parse_stretch (const char *str, case 'C': if (g_strcasecmp (str, "condensed") == 0) { - desc->stretch = PANGO_STRETCH_CONDENSED; + *stretch = PANGO_STRETCH_CONDENSED; return TRUE; } break; @@ -827,18 +827,18 @@ pango_parse_stretch (const char *str, if (g_strcasecmp (str, "extra_condensed") == 0 || g_strcasecmp (str, "extracondensed") == 0) { - desc->stretch = PANGO_STRETCH_EXTRA_CONDENSED; + *stretch = PANGO_STRETCH_EXTRA_CONDENSED; return TRUE; } if (g_strcasecmp (str, "extra_expanded") == 0 || g_strcasecmp (str, "extraexpanded") == 0) { - desc->stretch = PANGO_STRETCH_EXTRA_EXPANDED; + *stretch = PANGO_STRETCH_EXTRA_EXPANDED; return TRUE; } if (g_strcasecmp (str, "expanded") == 0) { - desc->stretch = PANGO_STRETCH_EXPANDED; + *stretch = PANGO_STRETCH_EXPANDED; return TRUE; } break; @@ -846,7 +846,7 @@ pango_parse_stretch (const char *str, case 'N': if (g_strcasecmp (str, "normal") == 0) { - desc->stretch = PANGO_STRETCH_NORMAL; + *stretch = PANGO_STRETCH_NORMAL; return TRUE; } break; @@ -855,13 +855,13 @@ pango_parse_stretch (const char *str, if (g_strcasecmp (str, "semi_condensed") == 0 || g_strcasecmp (str, "semicondensed") == 0) { - desc->stretch = PANGO_STRETCH_SEMI_CONDENSED; + *stretch = PANGO_STRETCH_SEMI_CONDENSED; return TRUE; } if (g_strcasecmp (str, "semi_expanded") == 0 || g_strcasecmp (str, "semiexpanded") == 0) { - desc->stretch = PANGO_STRETCH_SEMI_EXPANDED; + *stretch = PANGO_STRETCH_SEMI_EXPANDED; return TRUE; } break; @@ -870,13 +870,13 @@ pango_parse_stretch (const char *str, if (g_strcasecmp (str, "ultra_condensed") == 0 || g_strcasecmp (str, "ultracondensed") == 0) { - desc->stretch = PANGO_STRETCH_ULTRA_CONDENSED; + *stretch = PANGO_STRETCH_ULTRA_CONDENSED; return TRUE; } if (g_strcasecmp (str, "ultra_expanded") == 0 || g_strcasecmp (str, "ultraexpanded") == 0) { - desc->variant = PANGO_STRETCH_ULTRA_EXPANDED; + *stretch = PANGO_STRETCH_ULTRA_EXPANDED; return TRUE; } break; @@ -1016,6 +1016,8 @@ pango_language_from_string (const char *language) * in the list if the range is '*', the range is exactly the tag, * or the range is a prefix of the tag, and the character after the * tag is '-'. + * + * Returns: %TRUE if a match was found. **/ gboolean pango_language_matches (PangoLanguage *language, diff --git a/pango/pango-utils.h b/pango/pango-utils.h index 995f772b..e45d219c 100644 --- a/pango/pango-utils.h +++ b/pango/pango-utils.h @@ -23,12 +23,13 @@ #include #include -char *pango_trim_string (const char *str); char ** pango_split_file_list (const char *str); +#ifdef PANGO_ENABLE_BACKEND + +char *pango_trim_string (const char *str); gint pango_read_line (FILE *stream, GString *str); - gboolean pango_skip_space (const char **pos); gboolean pango_scan_word (const char **pos, GString *out); @@ -39,6 +40,8 @@ gboolean pango_scan_int (const char **pos, char * pango_config_key_get (const char *key); +#endif /* PANGO_ENABLE_BACKEND */ + /* Functions for parsing textual representations * of PangoFontDescription fields. They return TRUE if the input string * contains a valid value, which then has been assigned to the corresponding @@ -46,18 +49,20 @@ char * pango_config_key_get (const char *key); * a warning is printed (with g_warning) if the string does not * contain a valid value. */ -gboolean pango_parse_style (const char *str, - PangoFontDescription *desc, - gboolean warn); -gboolean pango_parse_variant (const char *str, - PangoFontDescription *desc, - gboolean warn); -gboolean pango_parse_weight (const char *str, - PangoFontDescription *desc, - gboolean warn); -gboolean pango_parse_stretch (const char *str, - PangoFontDescription *desc, - gboolean warn); +gboolean pango_parse_style (const char *str, + PangoStyle *style, + gboolean warn); +gboolean pango_parse_variant (const char *str, + PangoVariant *variant, + gboolean warn); +gboolean pango_parse_weight (const char *str, + PangoWeight *weight, + gboolean warn); +gboolean pango_parse_stretch (const char *str, + PangoStretch *stretch, + gboolean warn); + +#ifdef PANGO_ENABLE_BACKEND /* On Unix, return the name of the "pango" subdirectory of SYSCONFDIR * (which is set at compile time). On Win32, return the Pango @@ -73,6 +78,8 @@ G_CONST_RETURN char * pango_get_sysconf_subdirectory (void); */ G_CONST_RETURN char * pango_get_lib_subdirectory (void); +#endif /* PANGO_ENABLE_BACKEND */ + /* A couple of routines from fribidi that we either wrap or * provide ourselves. */ @@ -81,7 +88,6 @@ gboolean pango_log2vis_get_embedding_levels (gunichar *str, PangoDirection *pbase_dir, guint8 *embedding_level_list); gboolean pango_get_mirror_char (gunichar ch, - gunichar *mirrored_ch); G_CONST_RETURN char *pango_language_get_sample_string (PangoLanguage *language); diff --git a/pango/pango.h b/pango/pango.h index b5691901..ae440e03 100644 --- a/pango/pango.h +++ b/pango/pango.h @@ -22,10 +22,6 @@ #ifndef __PANGO_H__ #define __PANGO_H__ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - #include #include #include @@ -39,9 +35,4 @@ extern "C" { #include #include -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - #endif /* __PANGO_H__ */ diff --git a/pango/pangoft2-fontmap.c b/pango/pangoft2-fontmap.c index d575d968..0cd61109 100644 --- a/pango/pangoft2-fontmap.c +++ b/pango/pangoft2-fontmap.c @@ -43,14 +43,10 @@ #define PANGO_TYPE_FT2_FONT_MAP (pango_ft2_font_map_get_type ()) #define PANGO_FT2_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FT2_FONT_MAP, PangoFT2FontMap)) -#define PANGO_FT2_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FT2_FONT_MAP, PangoFT2FontMapClass)) #define PANGO_FT2_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FT2_FONT_MAP)) -#define PANGO_FT2_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FT2_FONT_MAP)) -#define PANGO_FT2_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FT2_FONT_MAP, PangoFontMapClass)) -typedef struct _PangoFT2FamilyEntry PangoFT2FamilyEntry; +typedef struct _PangoFT2Family PangoFT2Family; typedef struct _PangoFT2FontMap PangoFT2FontMap; -typedef struct _PangoFT2FontMapClass PangoFT2FontMapClass; typedef struct _PangoFT2SizeInfo PangoFT2SizeInfo; /* Number of freed fonts */ @@ -76,12 +72,7 @@ struct _PangoFT2FontMap double resolution; /* (points / pixel) * PANGO_SCALE */ }; -struct _PangoFT2FontMapClass -{ - PangoFontMapClass parent_class; -}; - -struct _PangoFT2FamilyEntry +struct _PangoFT2Family { char *family_name; @@ -89,23 +80,29 @@ struct _PangoFT2FamilyEntry GSList *font_entries; }; -static GType pango_ft2_font_map_get_type (void); +#define PANGO_FT2_TYPE_FAMILY (pango_ft2_family_get_type ()) +#define PANGO_FT2_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FT2_TYPE_FAMILY, PangoFT2Family)) +#define PANGO_FT2_IS_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FT2_TYPE_FAMILY)) + +#define PANGO_FT2_TYPE_FACE (pango_ft2_face_get_type ()) +#define PANGO_FT2_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FT2_TYPE_FACE, PangoFT2Face)) +#define PANGO_FT2_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_FT2_TYPE_FACE)) + +static GType pango_ft2_font_map_get_type (void); +GType pango_ft2_family_get_type (void); +GType pango_ft2_face_get_type (void); static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap); -static void pango_ft2_font_map_class_init (PangoFT2FontMapClass *class); +static void pango_ft2_font_map_class_init (PangoFontMapClass *class); static void pango_ft2_font_map_finalize (GObject *object); static PangoFont *pango_ft2_font_map_load_font (PangoFontMap *fontmap, const PangoFontDescription *description); -static void pango_ft2_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); static void pango_ft2_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, + PangoFontFamily ***families, int *n_families); static void pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap); @@ -131,7 +128,7 @@ pango_ft2_font_map_get_type (void) { static const GTypeInfo object_info = { - sizeof (PangoFT2FontMapClass), + sizeof (PangoFontMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_ft2_font_map_class_init, @@ -150,50 +147,26 @@ pango_ft2_font_map_get_type (void) return object_type; } -static guint -face_style_hash (gconstpointer v) -{ - PangoFontDescription *desc = (PangoFontDescription *)v; - - return g_str_hash (desc->family_name) + - desc->style + desc->variant + desc->weight + desc->stretch; -} - -static gint -face_style_equal (gconstpointer v1, - gconstpointer v2) -{ - PangoFontDescription *desc1 = (PangoFontDescription *)v1; - PangoFontDescription *desc2 = (PangoFontDescription *)v2; - - return (g_strcasecmp (desc1->family_name, desc2->family_name) == 0 && - desc1->style == desc2->style && - desc1->variant == desc2->variant && - desc1->weight == desc2->weight && - desc1->stretch == desc2->stretch); -} - static void pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap) { ft2fontmap->families = g_hash_table_new (g_str_hash, g_str_equal); - ft2fontmap->faces = g_hash_table_new (face_style_hash, face_style_equal); + ft2fontmap->faces = g_hash_table_new ((GHashFunc)pango_font_description_hash, + (GEqualFunc)pango_font_description_equal); ft2fontmap->n_fonts = 0; } static void -pango_ft2_font_map_class_init (PangoFT2FontMapClass *class) +pango_ft2_font_map_class_init (PangoFontMapClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - PangoFontMapClass *font_map_class = PANGO_FONT_MAP_CLASS (class); char *font_path; parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_ft2_font_map_finalize; - font_map_class->load_font = pango_ft2_font_map_load_font; - font_map_class->list_fonts = pango_ft2_font_map_list_fonts; - font_map_class->list_families = pango_ft2_font_map_list_families; + class->load_font = pango_ft2_font_map_load_font; + class->list_families = pango_ft2_font_map_list_families; font_path = pango_config_key_get ("PangoFT2/FontPath"); @@ -374,95 +347,18 @@ pango_ft2_font_map_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -typedef struct -{ - int n_found; - PangoFontDescription **descs; -} ListFontsInfo; - -static void -list_fonts_foreach (gpointer key, - gpointer value, - gpointer user_data) -{ - PangoFT2FamilyEntry *entry = value; - ListFontsInfo *info = user_data; - - GSList *tmp_list = entry->font_entries; - - while (tmp_list) - { - PangoFT2FontEntry *font_entry = tmp_list->data; - - info->descs[info->n_found++] = pango_font_description_copy (&font_entry->description); - tmp_list = tmp_list->next; - } -} - -static void -pango_ft2_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs) -{ - PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; - ListFontsInfo info; - - if (!n_descs) - return; - - if (family) - { - PangoFT2FamilyEntry *entry = g_hash_table_lookup (ft2fontmap->families, family); - if (entry) - { - *n_descs = g_slist_length (entry->font_entries); - if (descs) - { - *descs = g_new (PangoFontDescription *, *n_descs); - - info.descs = *descs; - info.n_found = 0; - - list_fonts_foreach ((gpointer)family, (gpointer)entry, &info); - } - } - else - { - *n_descs = 0; - if (descs) - *descs = NULL; - } - } - else - { - *n_descs = ft2fontmap->n_fonts; - if (descs) - { - *descs = g_new (PangoFontDescription *, ft2fontmap->n_fonts); - - info.descs = *descs; - info.n_found = 0; - - g_hash_table_foreach (ft2fontmap->families, list_fonts_foreach, &info); - } - } -} - static void -list_families_foreach (gpointer key, - gpointer value, - gpointer user_data) +list_families_foreach (gpointer key, gpointer value, gpointer user_data) { GSList **list = user_data; - *list = g_slist_prepend (*list, key); + *list = g_slist_prepend (*list, value); } static void -pango_ft2_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, - int *n_families) +pango_ft2_font_map_list_families (PangoFontMap *fontmap, + PangoFontFamily ***families, + int *n_families) { GSList *family_list = NULL; GSList *tmp_list; @@ -479,12 +375,12 @@ pango_ft2_font_map_list_families (PangoFontMap *fontmap, { int i = 0; - *families = g_new (gchar *, *n_families); + *families = g_new (PangoFontFamily *, *n_families); tmp_list = family_list; while (tmp_list) { - (*families)[i] = g_strdup (tmp_list->data); + (*families)[i] = tmp_list->data; i++; tmp_list = tmp_list->next; } @@ -493,21 +389,21 @@ pango_ft2_font_map_list_families (PangoFontMap *fontmap, g_slist_free (family_list); } -static PangoFT2FamilyEntry * -pango_ft2_get_family_entry (PangoFT2FontMap *ft2fontmap, - const char *family_name) +static PangoFT2Family * +pango_ft2_get_family (PangoFT2FontMap *ft2fontmap, + const char *family_name) { - PangoFT2FamilyEntry *family_entry = g_hash_table_lookup (ft2fontmap->families, family_name); - if (!family_entry) + PangoFT2Family *ft2family = g_hash_table_lookup (ft2fontmap->families, family_name); + if (!ft2family) { - family_entry = g_new (PangoFT2FamilyEntry, 1); - family_entry->family_name = g_strdup (family_name); - family_entry->font_entries = NULL; + ft2family = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL); + ft2family->family_name = g_strdup (family_name); + ft2family->font_entries = NULL; - g_hash_table_insert (ft2fontmap->families, family_entry->family_name, family_entry); + g_hash_table_insert (ft2fontmap->families, ft2family->family_name, ft2family); } - return family_entry; + return ft2family; } static PangoFont * @@ -515,42 +411,32 @@ pango_ft2_font_map_load_font (PangoFontMap *fontmap, const PangoFontDescription *description) { PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; - PangoFT2FamilyEntry *family_entry; + PangoFT2Family *family_entry; PangoFont *result = NULL; GSList *tmp_list; gchar *name; g_return_val_if_fail (description != NULL, NULL); - g_return_val_if_fail (description->size > 0, NULL); - name = g_strdup (description->family_name); - g_strdown (name); + name = g_ascii_strdown (pango_font_description_get_family (description)); family_entry = g_hash_table_lookup (ft2fontmap->families, name); g_free (name); if (family_entry) { - PangoFT2FontEntry *best_match = NULL; + PangoFT2Face *best_match = NULL; tmp_list = family_entry->font_entries; while (tmp_list) { - PangoFT2FontEntry *font_entry = tmp_list->data; + PangoFT2Face *face = tmp_list->data; + + if (pango_font_description_better_match (description, + best_match ? best_match->description : NULL, + face->description)) + best_match = face; - if (font_entry->description.style == description->style && - font_entry->description.variant == description->variant && - font_entry->description.stretch == description->stretch) - { - int distance = abs (font_entry->description.weight - description->weight); - int old_distance = best_match ? abs (best_match->description.weight - description->weight) : G_MAXINT; - - if (distance < old_distance) - { - best_match = font_entry; - } - } - tmp_list = tmp_list->next; } @@ -558,11 +444,13 @@ pango_ft2_font_map_load_font (PangoFontMap *fontmap, { GSList *tmp_list = best_match->cached_fonts; + gint size = pango_font_description_get_size (description); + while (tmp_list) { PangoFT2Font *ft2font = tmp_list->data; - if (ft2font->size == description->size) + if (ft2font->size == size) { result = (PangoFont *)ft2font; @@ -581,7 +469,7 @@ pango_ft2_font_map_load_font (PangoFontMap *fontmap, best_match->open_args, best_match->face_indices, best_match->n_fonts, - description->size); + size); ft2font->fontmap = fontmap; ft2font->entry = best_match; @@ -603,7 +491,7 @@ pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, int lineno = 0; int nfaces; int i; - PangoFT2FontEntry *font_entry = NULL; + PangoFT2Face *face = NULL; gchar **faces; gboolean ret_val = FALSE; @@ -615,7 +503,11 @@ pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, while (pango_read_line (infile, line_buf)) { - PangoFT2FamilyEntry *family_entry; + PangoFT2Family *family_entry; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; const char *p = line_buf->str; @@ -627,37 +519,43 @@ pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, if (!pango_scan_string (&p, tmp_buf)) goto error; - font_entry = g_new (PangoFT2FontEntry, 1); - font_entry->n_fonts = 0; - font_entry->open_args = NULL; - font_entry->face_indices = NULL; + face = g_new (PangoFT2Face, 1); + face->n_fonts = 0; + face->open_args = NULL; + face->face_indices = NULL; - font_entry->description.family_name = g_strdup (tmp_buf->str); - g_strdown (font_entry->description.family_name); + face->description = pango_font_description_new (); + g_string_ascii_down (tmp_buf); + pango_font_description_set_family (face->description, tmp_buf->str); + if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_style (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_style (tmp_buf->str, &style, TRUE)) goto error; + pango_font_description_set_style (face->description, style); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_variant (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_variant (tmp_buf->str, &variant, TRUE)) goto error; - + pango_font_description_set_variant (face->description, variant); + if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_weight (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_weight (tmp_buf->str, &weight, TRUE)) goto error; + pango_font_description_set_weight (face->description, weight); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_stretch (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE)) goto error; + pango_font_description_set_stretch (face->description, stretch); if (!pango_scan_string (&p, tmp_buf)) goto error; @@ -674,39 +572,40 @@ pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, nfaces++; } - font_entry->open_args = g_new (FT_Open_Args *, nfaces); - font_entry->face_indices = g_new (FT_Long, nfaces); + face->open_args = g_new (FT_Open_Args *, nfaces); + face->face_indices = g_new (FT_Long, nfaces); for (i = 0; i < nfaces; i++) { - PangoFontDescription desc; + PangoFontDescription *desc = pango_font_description_copy_static (face->description); PangoFT2OA *oa; - desc = font_entry->description; - desc.family_name = faces[i]; - oa = g_hash_table_lookup (ft2fontmap->faces, &desc); + pango_font_description_set_family_static (desc, faces[i]); + oa = g_hash_table_lookup (ft2fontmap->faces, desc); if (!oa) g_warning ("Face '%s' on line %d of '%s' not found", faces[i], lineno, filename); else { - font_entry->open_args[font_entry->n_fonts] = oa->open_args; - font_entry->face_indices[font_entry->n_fonts] = oa->face_index; - font_entry->n_fonts++; + face->open_args[face->n_fonts] = oa->open_args; + face->face_indices[face->n_fonts] = oa->face_index; + face->n_fonts++; } + + pango_font_description_free (desc); } g_strfreev (faces); /* Insert the font entry into our structures */ - family_entry = pango_ft2_get_family_entry (ft2fontmap, font_entry->description.family_name); - family_entry->font_entries = g_slist_prepend (family_entry->font_entries, font_entry); + family_entry = pango_ft2_get_family (ft2fontmap, pango_font_description_get_family (face->description)); + family_entry->font_entries = g_slist_prepend (family_entry->font_entries, face); ft2fontmap->n_fonts++; - g_free (font_entry->description.family_name); - font_entry->description.family_name = family_entry->family_name; - font_entry->cached_fonts = NULL; - font_entry->coverage = NULL; + /* Save space by consolidating duplicated string */ + pango_font_description_set_family_static (face->description, family_entry->family_name); + face->cached_fonts = NULL; + face->coverage = NULL; } if (ferror (infile)) @@ -716,15 +615,15 @@ pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, goto out; error: - if (font_entry) + if (face) { - if (font_entry->open_args) - g_free (font_entry->open_args); - if (font_entry->face_indices) - g_free (font_entry->face_indices); - if (font_entry->description.family_name) - g_free (font_entry->description.family_name); - g_free (font_entry); + if (face->open_args) + g_free (face->open_args); + if (face->face_indices) + g_free (face->face_indices); + if (face->description) + pango_font_description_free (face->description); + g_free (face); } g_warning ("Error parsing line %d of alias file '%s'", lineno, filename); @@ -793,32 +692,37 @@ pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap) static void pango_print_desc (PangoFontDescription *desc) { + PangoStyle style = pango_font_description_get_style (desc); + PangoVariant variant = pango_font_description_get_variant (desc); + PangoWeight weight = pango_font_description_get_weight (desc); + PangoStretch stretch = pango_font_description_get_stretch (desc); + g_print ("%s%s%s%s%s", - desc->family_name, - (desc->style == PANGO_STYLE_NORMAL ? "" : - (desc->style == PANGO_STYLE_OBLIQUE ? " OBLIQUE" : - (desc->style == PANGO_STYLE_ITALIC ? " ITALIC" : " ???"))), - (desc->variant == PANGO_VARIANT_NORMAL ? "" : - (desc->variant == PANGO_VARIANT_SMALL_CAPS ? " SMALL CAPS" : "???")), - (desc->weight >= (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 && - desc->weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 ? "" : - (desc->weight < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 ? " ULTRALIGHT" : - (desc->weight >= (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 && - desc->weight < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 ? " LIGHT" : - (desc->weight >= (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 && - desc->weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 ? " BOLD" : - (desc->weight >= (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 && - desc->weight < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2 ? " ULTRABOLD" : + pango_font_get_family (desc), + (style == PANGO_STYLE_NORMAL ? "" : + (style == PANGO_STYLE_OBLIQUE ? " OBLIQUE" : + (style == PANGO_STYLE_ITALIC ? " ITALIC" : " ???"))), + (variant == PANGO_VARIANT_NORMAL ? "" : + (variant == PANGO_VARIANT_SMALL_CAPS ? " SMALL CAPS" : "???")), + (weight >= (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 && + weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 ? "" : + (weight < (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 ? " ULTRALIGHT" : + (weight >= (PANGO_WEIGHT_ULTRALIGHT + PANGO_WEIGHT_LIGHT) / 2 && + weight < (PANGO_WEIGHT_LIGHT + PANGO_WEIGHT_NORMAL) / 2 ? " LIGHT" : + (weight >= (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_BOLD) / 2 && + weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 ? " BOLD" : + (weight >= (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2 && + weight < (PANGO_WEIGHT_ULTRABOLD + PANGO_WEIGHT_HEAVY) / 2 ? " ULTRABOLD" : " HEAVY"))))), - (desc->stretch == PANGO_STRETCH_ULTRA_CONDENSED ? " ULTRA CONDENSED" : - (desc->stretch == PANGO_STRETCH_EXTRA_CONDENSED ? " EXTRA CONDENSED" : - (desc->stretch == PANGO_STRETCH_CONDENSED ? " CONDENSED" : - (desc->stretch == PANGO_STRETCH_SEMI_CONDENSED ? " SEMI CONDENSED" : - (desc->stretch == PANGO_STRETCH_NORMAL ? "" : - (desc->stretch == PANGO_STRETCH_SEMI_EXPANDED ? " SEMI EXPANDED" : - (desc->stretch == PANGO_STRETCH_EXPANDED ? " EXPANDED" : - (desc->stretch == PANGO_STRETCH_EXTRA_EXPANDED ? " EXTRA EXPANDED" : - (desc->stretch == PANGO_STRETCH_ULTRA_EXPANDED ? " ULTRA EXPANDED" : " ???")))))))))); + (stretch == PANGO_STRETCH_ULTRA_CONDENSED ? " ULTRA CONDENSED" : + (stretch == PANGO_STRETCH_EXTRA_CONDENSED ? " EXTRA CONDENSED" : + (stretch == PANGO_STRETCH_CONDENSED ? " CONDENSED" : + (stretch == PANGO_STRETCH_SEMI_CONDENSED ? " SEMI CONDENSED" : + (stretch == PANGO_STRETCH_NORMAL ? "" : + (stretch == PANGO_STRETCH_SEMI_EXPANDED ? " SEMI EXPANDED" : + (stretch == PANGO_STRETCH_EXPANDED ? " EXPANDED" : + (stretch == PANGO_STRETCH_EXTRA_EXPANDED ? " EXTRA EXPANDED" : + (stretch == PANGO_STRETCH_ULTRA_EXPANDED ? " ULTRA EXPANDED" : " ???")))))))))); } static void @@ -836,29 +740,32 @@ pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap, int face_index) { PangoFontDescription *description; + char *family_name; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; GSList *tmp_list; - PangoFT2FamilyEntry *family_entry; - PangoFT2FontEntry *font_entry; + PangoFT2Family *family_entry; + PangoFT2Face *face_entry; PangoFT2OA *oa; FT_Open_Args *open_args; - description = g_new (PangoFontDescription, 1); - description->family_name = g_strdup (face->family_name); - g_strdown (description->family_name); + family_name = g_ascii_strdown (face->family_name); if (face->style_flags & FT_STYLE_FLAG_ITALIC) - description->style = PANGO_STYLE_ITALIC; + style = PANGO_STYLE_ITALIC; else - description->style = PANGO_STYLE_NORMAL; + style = PANGO_STYLE_NORMAL; - description->variant = PANGO_VARIANT_NORMAL; + variant = PANGO_VARIANT_NORMAL; if (face->style_flags & FT_STYLE_FLAG_BOLD) - description->weight = PANGO_WEIGHT_BOLD; + weight = PANGO_WEIGHT_BOLD; else - description->weight = PANGO_WEIGHT_NORMAL; + weight = PANGO_WEIGHT_NORMAL; - description->stretch = PANGO_STRETCH_NORMAL; + stretch = PANGO_STRETCH_NORMAL; if (face->style_name) { @@ -867,36 +774,33 @@ pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap, while (styles[i]) { - (void) (pango_parse_style (styles[i], description, FALSE) || - pango_parse_variant (styles[i], description, FALSE) || - pango_parse_weight (styles[i], description, FALSE) || - pango_parse_stretch (styles[i], description, FALSE)); + (void) (pango_parse_style (styles[i], &style, FALSE) || + pango_parse_variant (styles[i], &variant, FALSE) || + pango_parse_weight (styles[i], &weight, FALSE) || + pango_parse_stretch (styles[i], &stretch, FALSE)); i++; } g_strfreev (styles); } - description->size = 0; - #if 0 PING (("")); pango_print_desc (description); #endif - family_entry = pango_ft2_get_family_entry (ft2fontmap, description->family_name); + family_entry = pango_ft2_get_family (ft2fontmap, family_name); + g_free (family_name); tmp_list = family_entry->font_entries; while (tmp_list) { - font_entry = tmp_list->data; + face_entry = tmp_list->data; - if (font_entry->description.style == description->style && - font_entry->description.variant == description->variant && - font_entry->description.weight == description->weight && - font_entry->description.stretch == description->stretch) + if (pango_font_description_get_style (face_entry->description) == style && + pango_font_description_get_weight (face_entry->description) == weight && + pango_font_description_get_stretch (face_entry->description) == stretch && + pango_font_description_get_variant (face_entry->description) == variant) { - g_free (description->family_name); - g_free (description); #if 0 PING ((" family and description matched (!)")); #endif @@ -906,6 +810,13 @@ pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap, tmp_list = tmp_list->next; } + description = pango_font_description_new (); + pango_font_description_set_family_static (description, family_entry->family_name); + pango_font_description_set_style (description, style); + pango_font_description_set_weight (description, weight); + pango_font_description_set_stretch (description, stretch); + pango_font_description_set_variant (description, variant); + oa = g_hash_table_lookup (ft2fontmap->faces, description); if (!oa) { @@ -927,17 +838,16 @@ pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap, g_print ("\n"); #endif - font_entry = g_new (PangoFT2FontEntry, 1); - font_entry->description = *description; - font_entry->description.family_name = family_entry->family_name; - font_entry->cached_fonts = NULL; - font_entry->coverage = NULL; - font_entry->open_args = g_new (FT_Open_Args *, 1); - font_entry->open_args[0] = oa->open_args; - font_entry->face_indices = g_new (FT_Long, 1); - font_entry->face_indices[0] = oa->face_index; - font_entry->n_fonts = 1; - family_entry->font_entries = g_slist_append (family_entry->font_entries, font_entry); + face_entry = g_object_new (PANGO_FT2_TYPE_FACE, NULL); + face_entry->description = description; + face_entry->cached_fonts = NULL; + face_entry->coverage = NULL; + face_entry->open_args = g_new (FT_Open_Args *, 1); + face_entry->open_args[0] = oa->open_args; + face_entry->face_indices = g_new (FT_Long, 1); + face_entry->face_indices[0] = oa->face_index; + face_entry->n_fonts = 1; + family_entry->font_entries = g_slist_append (family_entry->font_entries, face_entry); ft2fontmap->n_fonts++; } @@ -949,10 +859,208 @@ free_coverages_foreach (gpointer key, pango_coverage_unref (value); } +PangoFT2FontCache * +pango_ft2_font_map_get_font_cache (PangoFontMap *font_map) +{ + g_return_val_if_fail (font_map != NULL, NULL); + g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (font_map), NULL); + + return PANGO_FT2_FONT_MAP (font_map)->font_cache; +} + +void +pango_ft2_fontmap_cache_add (PangoFontMap *fontmap, + PangoFT2Font *ft2font) +{ + PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + + if (ft2fontmap->freed_fonts->length == MAX_FREED_FONTS) + { + PangoFT2Font *old_font = g_queue_pop_tail (ft2fontmap->freed_fonts); + g_object_unref (G_OBJECT (old_font)); + } + + g_object_ref (G_OBJECT (ft2font)); + g_queue_push_head (ft2fontmap->freed_fonts, ft2font); + ft2font->in_cache = TRUE; +} + +void +pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap, + PangoFT2Font *ft2font) +{ + PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + + GList *link = g_list_find (ft2fontmap->freed_fonts->head, ft2font); + if (link == ft2fontmap->freed_fonts->tail) + { + ft2fontmap->freed_fonts->tail = ft2fontmap->freed_fonts->tail->prev; + if (ft2fontmap->freed_fonts->tail) + ft2fontmap->freed_fonts->tail->next = NULL; + } + + ft2fontmap->freed_fonts->head = g_list_delete_link (ft2fontmap->freed_fonts->head, link); + ft2fontmap->freed_fonts->length--; + ft2font->in_cache = FALSE; + + g_object_unref (G_OBJECT (ft2font)); +} + +static void +pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap) +{ + g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); + g_list_free (ft2fontmap->freed_fonts->head); + ft2fontmap->freed_fonts->head = NULL; + ft2fontmap->freed_fonts->tail = NULL; + ft2fontmap->freed_fonts->length = 0; +} + +static void +pango_ft2_face_dump (int indent, + PangoFT2Face *face) +{ + int i; + + printf ("%*sPangoFT2Face@%p:\n" + "%*s lfp:\n", + indent, "", face, + indent, ""); + + for (i = 0; i < face->n_fonts; i++) + printf ("%*s PangoFT2OpenArgs:%s:%ld\n", + indent, "", face->open_args[i]->pathname, face->face_indices[i]); + + printf ("%*s description:\n" + "%*s family_name: %s\n" + "%*s style: %d\n" + "%*s variant: %d\n" + "%*s weight: %d\n" + "%*s stretch: %d\n" + "%*s coverage: %p\n", + indent, "", + indent, "", pango_font_description_get_family (face->description), + indent, "", pango_font_description_get_style (face->description), + indent, "", pango_font_description_get_variant (face->description), + indent, "", pango_font_description_get_weight (face->description), + indent, "", pango_font_description_get_stretch (face->description), + indent, "", face->coverage); +} + +static void +pango_ft2_family_entry_dump (int indent, + PangoFT2Family *entry) +{ + GSList *tmp_list = entry->font_entries; + + printf ("%*sPangoFT2Family@%p:\n" + "%*s family_name: %s\n" + "%*s font_entries:\n", + indent, "", entry, + indent, "", entry->family_name, + indent, ""); + + while (tmp_list) + { + PangoFT2Face *face = tmp_list->data; + + pango_ft2_face_dump (indent + 2, face); + tmp_list = tmp_list->next; + } +} + +static void +dump_family (gpointer key, + gpointer value, + gpointer user_data) +{ + PangoFT2Family *entry = value; + int indent = (int) user_data; + + pango_ft2_family_entry_dump (indent, entry); +} + +void +pango_ft2_fontmap_dump (int indent, + PangoFontMap *fontmap) +{ + PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + + printf ("%*sPangoFT2FontMap@%p:\n", + indent, "", ft2fontmap); + g_hash_table_foreach (ft2fontmap->families, dump_family, (gpointer) (indent + 2)); +} + +/* + * PangoFT2Face + */ + +static PangoFontDescription * +pango_ft2_face_describe (PangoFontFace *face) +{ + PangoFT2Face *ft2face = PANGO_FT2_FACE (face); + + return pango_font_description_copy (ft2face->description); +} + +static const char * +pango_ft2_face_get_face_name (PangoFontFace *face) +{ + PangoFT2Face *ft2face = PANGO_FT2_FACE (face); + + if (!ft2face->face_name) + { + PangoFontDescription *desc = pango_font_face_describe (face); + + pango_font_description_unset_fields (desc, + PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); + + ft2face->face_name = pango_font_description_to_string (desc); + pango_font_description_free (desc); + } + + return ft2face->face_name; +} + +static void +pango_ft2_face_class_init (PangoFontFaceClass *class) +{ + class->describe = pango_ft2_face_describe; + class->get_face_name = pango_ft2_face_get_face_name; +} + +GType +pango_ft2_face_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (PangoFontFaceClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_ft2_face_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoFT2Face), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, + "PangoFT2Face", + &object_info, 0); + } + + return object_type; +} + PangoCoverage * -pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, - PangoFont *font, - PangoLanguage *language) +pango_ft2_face_get_coverage (PangoFT2Face *face, + PangoFont *font, + PangoLanguage *language) { guint32 ch; PangoMap *shape_map; @@ -969,11 +1077,11 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, guchar *buf; size_t buflen; - if (entry) - if (entry->coverage) + if (face) + if (face->coverage) { - pango_coverage_ref (entry->coverage); - return entry->coverage; + pango_coverage_ref (face->coverage); + return face->coverage; } description = pango_font_describe (font); @@ -1039,9 +1147,9 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, } } - if (entry) + if (face) { - entry->coverage = result; + face->coverage = result; pango_coverage_ref (result); } @@ -1051,140 +1159,78 @@ pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, } void -pango_ft2_font_entry_remove (PangoFT2FontEntry *entry, - PangoFont *font) +pango_ft2_face_remove (PangoFT2Face *face, + PangoFont *font) { - entry->cached_fonts = g_slist_remove (entry->cached_fonts, font); + face->cached_fonts = g_slist_remove (face->cached_fonts, font); } -PangoFT2FontCache * -pango_ft2_font_map_get_font_cache (PangoFontMap *font_map) -{ - g_return_val_if_fail (font_map != NULL, NULL); - g_return_val_if_fail (PANGO_FT2_IS_FONT_MAP (font_map), NULL); - - return PANGO_FT2_FONT_MAP (font_map)->font_cache; -} +/* + * PangoXFontFamily + */ -void -pango_ft2_fontmap_cache_add (PangoFontMap *fontmap, - PangoFT2Font *ft2font) +static void +pango_ft2_family_list_faces (PangoFontFamily *family, + PangoFontFace ***faces, + int *n_faces) { - PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + PangoFT2Family *ft2family = PANGO_FT2_FAMILY (family); - if (ft2fontmap->freed_fonts->length == MAX_FREED_FONTS) + *n_faces = g_slist_length (ft2family->font_entries); + if (faces) { - PangoFT2Font *old_font = g_queue_pop_tail (ft2fontmap->freed_fonts); - g_object_unref (G_OBJECT (old_font)); - } - - g_object_ref (G_OBJECT (ft2font)); - g_queue_push_head (ft2fontmap->freed_fonts, ft2font); - ft2font->in_cache = TRUE; -} - -void -pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap, - PangoFT2Font *ft2font) -{ - PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + GSList *tmp_list; + int i = 0; + + *faces = g_new (PangoFontFace *, *n_faces); - GList *link = g_list_find (ft2fontmap->freed_fonts->head, ft2font); - if (link == ft2fontmap->freed_fonts->tail) - { - ft2fontmap->freed_fonts->tail = ft2fontmap->freed_fonts->tail->prev; - if (ft2fontmap->freed_fonts->tail) - ft2fontmap->freed_fonts->tail->next = NULL; + tmp_list = ft2family->font_entries; + while (tmp_list) + { + (*faces)[i++] = tmp_list->data; + tmp_list = tmp_list->next; + } } - - ft2fontmap->freed_fonts->head = g_list_delete_link (ft2fontmap->freed_fonts->head, link); - ft2fontmap->freed_fonts->length--; - ft2font->in_cache = FALSE; - - g_object_unref (G_OBJECT (ft2font)); } -static void -pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap) +const char * +pango_ft2_family_get_name (PangoFontFamily *family) { - g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); - g_list_free (ft2fontmap->freed_fonts->head); - ft2fontmap->freed_fonts->head = NULL; - ft2fontmap->freed_fonts->tail = NULL; - ft2fontmap->freed_fonts->length = 0; + PangoFT2Family *ft2family = PANGO_FT2_FAMILY (family); + return ft2family->family_name; } static void -pango_ft2_font_entry_dump (int indent, - PangoFT2FontEntry *font_entry) +pango_ft2_family_class_init (PangoFontFamilyClass *class) { - int i; - - printf ("%*sPangoFT2FontEntry@%p:\n" - "%*s lfp:\n", - indent, "", font_entry, - indent, ""); - - for (i = 0; i < font_entry->n_fonts; i++) - printf ("%*s PangoFT2OpenArgs:%s:%ld\n", - indent, "", font_entry->open_args[i]->pathname, font_entry->face_indices[i]); - - printf ("%*s description:\n" - "%*s family_name: %s\n" - "%*s style: %d\n" - "%*s variant: %d\n" - "%*s weight: %d\n" - "%*s stretch: %d\n" - "%*s coverage: %p\n", - indent, "", - indent, "", font_entry->description.family_name, - indent, "", font_entry->description.style, - indent, "", font_entry->description.variant, - indent, "", font_entry->description.weight, - indent, "", font_entry->description.stretch, - indent, "", font_entry->coverage); + class->list_faces = pango_ft2_family_list_faces; + class->get_name = pango_ft2_family_get_name; } -static void -pango_ft2_family_entry_dump (int indent, - PangoFT2FamilyEntry *entry) +GType +pango_ft2_family_get_type (void) { - GSList *tmp_list = entry->font_entries; - - printf ("%*sPangoFT2FamilyEntry@%p:\n" - "%*s family_name: %s\n" - "%*s font_entries:\n", - indent, "", entry, - indent, "", entry->family_name, - indent, ""); + static GType object_type = 0; - while (tmp_list) + if (!object_type) { - PangoFT2FontEntry *font_entry = tmp_list->data; + static const GTypeInfo object_info = + { + sizeof (PangoFontFamilyClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_ft2_family_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoFT2Family), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; - pango_ft2_font_entry_dump (indent + 2, font_entry); - tmp_list = tmp_list->next; + object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, + "PangoFT2Family", + &object_info, 0); } -} - -static void -dump_family (gpointer key, - gpointer value, - gpointer user_data) -{ - PangoFT2FamilyEntry *entry = value; - int indent = (int) user_data; - - pango_ft2_family_entry_dump (indent, entry); -} - -void -pango_ft2_fontmap_dump (int indent, - PangoFontMap *fontmap) -{ - PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); - - printf ("%*sPangoFT2FontMap@%p:\n", - indent, "", ft2fontmap); - g_hash_table_foreach (ft2fontmap->families, dump_family, (gpointer) (indent + 2)); + + return object_type; } diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h index ff53c4ef..027ced1e 100644 --- a/pango/pangoft2-private.h +++ b/pango/pangoft2-private.h @@ -55,7 +55,7 @@ typedef struct _PangoFT2OA PangoFT2OA; typedef struct _PangoFT2Font PangoFT2Font; typedef struct _PangoFT2GlyphInfo PangoFT2GlyphInfo; -typedef struct _PangoFT2FontEntry PangoFT2FontEntry; +typedef struct _PangoFT2Face PangoFT2Face; typedef struct _PangoFT2SubfontInfo PangoFT2SubfontInfo; struct _PangoFT2OA @@ -88,7 +88,7 @@ struct _PangoFT2Font */ gboolean in_cache; - PangoFT2FontEntry *entry; + PangoFT2Face *entry; GHashTable *glyph_info; }; @@ -99,22 +99,23 @@ struct _PangoFT2GlyphInfo PangoRectangle ink_rect; }; -struct _PangoFT2FontEntry +struct _PangoFT2Face { FT_Open_Args **open_args; FT_Long *face_indices; int n_fonts; - PangoFontDescription description; + PangoFontDescription *description; PangoCoverage *coverage; + char *face_name; GSList *cached_fonts; }; PangoMap *pango_ft2_get_shaper_map (PangoLanguage *language); -PangoCoverage *pango_ft2_font_entry_get_coverage (PangoFT2FontEntry *entry, +PangoCoverage *pango_ft2_face_get_coverage (PangoFT2Face *face, PangoFont *font, PangoLanguage *language); -void pango_ft2_font_entry_remove (PangoFT2FontEntry *entry, +void pango_ft2_face_remove (PangoFT2Face *face, PangoFont *font); FT_Library *pango_ft2_fontmap_get_library (PangoFontMap *fontmap); void pango_ft2_fontmap_cache_add (PangoFontMap *fontmap, diff --git a/pango/pangoft2.c b/pango/pangoft2.c index 360388b8..271e0d1e 100644 --- a/pango/pangoft2.c +++ b/pango/pangoft2.c @@ -49,7 +49,7 @@ typedef struct _PangoFT2ContextInfo PangoFT2ContextInfo; struct _PangoFT2MetricsInfo { const char *sample_str; - PangoFontMetrics metrics; + PangoFontMetrics *metrics; }; struct _PangoFT2FontClass @@ -78,9 +78,8 @@ static void pango_ft2_font_get_glyph_extents (PangoFont PangoRectangle *ink_rect, PangoRectangle *logical_rect); -static void pango_ft2_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics); +static PangoFontMetrics * pango_ft2_font_get_metrics (PangoFont *font, + PangoLanguage *language); static void pango_ft2_get_item_properties (PangoItem *item, PangoUnderline *uline, @@ -577,7 +576,7 @@ get_font_metrics_from_string (PangoFont *font, guint8 *embedding_levels; PangoDirection base_dir = PANGO_DIRECTION_LTR; GSList *subfonts = NULL; - + text_ucs4 = g_utf8_to_ucs4_fast (str, -1, &n_chars); if (!text_ucs4) return; @@ -631,12 +630,13 @@ get_font_metrics_from_string (PangoFont *font, pango_glyph_string_free (glyph_str); g_free (embedding_levels); + + return; } -static void +static PangoFontMetrics * pango_ft2_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { PangoFT2MetricsInfo *info = NULL; /* Quiet GCC */ PangoFT2Font *ft2font = (PangoFT2Font *)font; @@ -659,13 +659,13 @@ pango_ft2_font_get_metrics (PangoFont *font, { info = g_new (PangoFT2MetricsInfo, 1); info->sample_str = sample_str; + info->metrics = pango_font_metrics_new (); + get_font_metrics_from_string (font, language, sample_str, info->metrics); ft2font->metrics_by_lang = g_slist_prepend (ft2font->metrics_by_lang, info); - - get_font_metrics_from_string (font, language, sample_str, &info->metrics); } - *metrics = info->metrics; + return pango_font_metrics_ref (info->metrics); } /** @@ -769,6 +769,13 @@ pango_ft2_free_glyph_info_callback (gpointer key, gpointer value, gpointer data) return TRUE; } +static void +free_metrics_info (PangoFT2MetricsInfo *info) +{ + pango_font_metrics_unref (info->metrics); + g_free (info); +} + static void pango_ft2_font_finalize (GObject *object) { @@ -787,11 +794,11 @@ pango_ft2_font_finalize (GObject *object) g_free (ft2font->oa); g_free (ft2font->faces); - g_slist_foreach (ft2font->metrics_by_lang, (GFunc)g_free, NULL); + g_slist_foreach (ft2font->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (ft2font->metrics_by_lang); if (ft2font->entry) - pango_ft2_font_entry_remove (ft2font->entry, (PangoFont *)ft2font); + pango_ft2_face_remove (ft2font->entry, (PangoFont *)ft2font); g_object_unref (G_OBJECT (ft2font->fontmap)); @@ -809,8 +816,8 @@ pango_ft2_font_describe (PangoFont *font) ft2font = PANGO_FT2_FONT (font); - desc = pango_font_description_copy (&ft2font->entry->description); - desc->size = ft2font->size; + desc = pango_font_description_copy (ft2font->entry->description); + pango_font_description_set_size (desc, ft2font->size); return desc; } @@ -836,7 +843,7 @@ pango_ft2_font_get_coverage (PangoFont *font, { PangoFT2Font *ft2font = (PangoFT2Font *)font; - return pango_ft2_font_entry_get_coverage (ft2font->entry, font, language); + return pango_ft2_face_get_coverage (ft2font->entry, font, language); } static PangoEngineShape * diff --git a/pango/pangoft2.h b/pango/pangoft2.h index 0613d2da..f2148d10 100644 --- a/pango/pangoft2.h +++ b/pango/pangoft2.h @@ -25,9 +25,7 @@ #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #include @@ -101,9 +99,6 @@ void pango_ft2_font_subfont_open_args (PangoFont *font, void pango_ft2_fontmap_dump (int indent, PangoFontMap *fontmap); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __PANGOFT2_H__ */ diff --git a/pango/pangowin32-fontmap.c b/pango/pangowin32-fontmap.c index 748100e9..4df6c257 100644 --- a/pango/pangowin32-fontmap.c +++ b/pango/pangowin32-fontmap.c @@ -442,31 +442,12 @@ pango_win32_font_map_load_font (PangoFontMap *fontmap, while (tmp_list) { PangoWin32FontEntry *font_entry = tmp_list->data; - - if (font_entry->description.variant == description->variant && - font_entry->description.stretch == description->stretch) - { - int old_distance = best_match ? abs(best_match->description.weight - description->weight) : G_MAXINT; - - if (font_entry->description.style == description->style) - { - int distance = abs(font_entry->description.weight - description->weight); - - if (distance < old_distance) - best_match = font_entry; - } - else if (font_entry->description.style != PANGO_STYLE_NORMAL && - description->style != PANGO_STYLE_NORMAL) - { - /* Equate oblique and italic, but with a big penalty - */ - int distance = PANGO_SCALE * 1000 + abs(font_entry->description.weight - description->weight); - - if (distance < old_distance) - best_match = font_entry; - } - } + if (pango_font_description_better_match (description, + best_match ? best_match->description : NULL, + font_entry->description)) + best_match = font_entry; + tmp_list = tmp_list->next; } @@ -529,6 +510,10 @@ pango_win32_font_map_read_alias_file (PangoWin32FontMap *win32fontmap, while (pango_read_line (infile, line_buf)) { PangoWin32FamilyEntry *family_entry; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; const char *p = line_buf->str; @@ -541,32 +526,38 @@ pango_win32_font_map_read_alias_file (PangoWin32FontMap *win32fontmap, goto error; font_entry = g_new (PangoWin32FontEntry, 1); - font_entry->description.family_name = g_strdup (tmp_buf->str); - g_strdown (font_entry->description.family_name); + font_entry->description = pango_font_description_new (); + g_string_ascii_down (tmp_buf); + pango_font_description_set_family (tmp_buf->str); + if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_style (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_style (tmp_buf->str, &style, TRUE)) goto error; + pango_font_description_set_style (font_entry->description, style); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_variant (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_variant (tmp_buf->str, &variant, TRUE)) goto error; - + pango_font_description_set_variant (font_entry->description, variant); + if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_weight (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_weight (tmp_buf->str, &weight, TRUE)) goto error; + pango_font_description_set_weight (font_entry->description, weight); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_stretch (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE)) goto error; + pango_font_description_set_stretch (font_entry->description, stretch); if (!pango_scan_string (&p, tmp_buf)) goto error; diff --git a/pango/pangowin32.c b/pango/pangowin32.c index 86a42432..169731d2 100644 --- a/pango/pangowin32.c +++ b/pango/pangowin32.c @@ -67,9 +67,8 @@ static void pango_win32_font_get_glyph_extents (PangoFont PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); -static void pango_win32_font_get_metrics (PangoFont *font, - PangoLanguage *lang, - PangoFontMetrics *metrics); +static PangoFontMetrics * pango_win32_font_get_metrics (PangoFont *font, + PangoLanguage *lang); static HFONT pango_win32_get_hfont (PangoFont *font); static void pango_win32_get_item_properties (PangoItem *item, PangoUnderline *uline, @@ -339,16 +338,18 @@ pango_win32_font_get_glyph_extents (PangoFont *font, *logical_rect = info->logical_rect; } -static void +static PangoFontMetrics * pango_win32_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { HFONT hfont; TEXTMETRIC tm; PangoLayout *layout; PangoRectangle extents; PangoContext *context; + PangoFontMetrics *metrics; + + metrics = pango_font_metrics_new (); metrics->ascent = 0; metrics->descent = 0; @@ -385,7 +386,7 @@ pango_win32_font_get_metrics (PangoFont *font, g_object_unref (G_OBJECT (context)); } - return; + return metrics; } diff --git a/pango/pangowin32.h b/pango/pangowin32.h index 2b80097c..ead670b8 100644 --- a/pango/pangowin32.h +++ b/pango/pangowin32.h @@ -27,9 +27,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #define STRICT #include @@ -84,9 +82,6 @@ PangoWin32FontCache *pango_win32_font_map_get_font_cache (PangoFontMap *fo LOGFONT *pango_win32_font_logfont (PangoFont *font); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __PANGOWIN32_H__ */ diff --git a/pango/pangox-fontmap.c b/pango/pangox-fontmap.c index ae92f507..c84ec0fb 100644 --- a/pango/pangox-fontmap.c +++ b/pango/pangox-fontmap.c @@ -32,7 +32,7 @@ #include "pango-utils.h" #include "pangox-private.h" -typedef struct _PangoXFamilyEntry PangoXFamilyEntry; +typedef struct _PangoXFamily PangoXFamily; typedef struct _PangoXSizeInfo PangoXSizeInfo; /* Number of freed fonts */ @@ -63,23 +63,24 @@ typedef enum XLFD_NUM_FIELDS } FontField; -struct _PangoXFontMapClass -{ - PangoFontMapClass parent_class; -}; - -struct _PangoXFamilyEntry +struct _PangoXFamily { + PangoFontFamily parent_instance; + char *family_name; GSList *font_entries; }; -struct _PangoXFontEntry +struct _PangoXFace { + PangoFontFace parent_instance; + char *xlfd; - PangoFontDescription description; + PangoFontDescription *description; PangoCoverage *coverage; + char *face_name; + GSList *cached_fonts; }; @@ -125,17 +126,13 @@ const struct { }; static void pango_x_font_map_init (PangoXFontMap *fontmap); -static void pango_x_font_map_class_init (PangoXFontMapClass *class); +static void pango_x_font_map_class_init (PangoFontMapClass *class); static void pango_x_font_map_finalize (GObject *object); static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap, const PangoFontDescription *description); -static void pango_x_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); static void pango_x_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, + PangoFontFamily ***families, int *n_families); static void pango_x_fontmap_cache_clear (PangoXFontMap *xfontmap); @@ -152,7 +149,21 @@ static char * pango_x_get_xlfd_field (const char *fontname, static char * pango_x_get_identifier (const char *fontname); -static PangoFontClass *parent_class; /* Parent class structure for PangoXFontMap */ +#define PANGO_X_TYPE_FAMILY (pango_x_family_get_type ()) +#define PANGO_X_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_X_TYPE_FAMILY, PangoXFamily)) +#define PANGO_X_IS_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_X_TYPE_FAMILY)) + +GType pango_x_family_get_type (void); + + +#define PANGO_X_TYPE_FACE (pango_x_face_get_type ()) +#define PANGO_X_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_X_TYPE_FACE, PangoXFace)) +#define PANGO_X_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_X_TYPE_FACE)) + +GType pango_x_face_get_type (void); + + +static PangoFontClass *font_map_parent_class; /* Parent class structure for PangoXFontMap */ GType pango_x_font_map_get_type (void) @@ -163,7 +174,7 @@ pango_x_font_map_get_type (void) { static const GTypeInfo object_info = { - sizeof (PangoXFontMapClass), + sizeof (PangoFontMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_x_font_map_class_init, @@ -193,17 +204,15 @@ pango_x_font_map_init (PangoXFontMap *xfontmap) } static void -pango_x_font_map_class_init (PangoXFontMapClass *class) +pango_x_font_map_class_init (PangoFontMapClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - PangoFontMapClass *font_map_class = PANGO_FONT_MAP_CLASS (class); - parent_class = g_type_class_peek_parent (class); + font_map_parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_x_font_map_finalize; - font_map_class->load_font = pango_x_font_map_load_font; - font_map_class->list_fonts = pango_x_font_map_list_fonts; - font_map_class->list_families = pango_x_font_map_list_families; + class->load_font = pango_x_font_map_load_font; + class->list_families = pango_x_font_map_list_families; } static GList *fontmaps = NULL; @@ -314,80 +323,7 @@ pango_x_font_map_finalize (GObject *object) fontmaps = g_list_remove (fontmaps, xfontmap); - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -typedef struct -{ - int n_found; - PangoFontDescription **descs; -} ListFontsInfo; - -static void -list_fonts_foreach (gpointer key, gpointer value, gpointer user_data) -{ - PangoXFamilyEntry *entry = value; - ListFontsInfo *info = user_data; - - GSList *tmp_list = entry->font_entries; - - while (tmp_list) - { - PangoXFontEntry *font_entry = tmp_list->data; - - info->descs[info->n_found++] = pango_font_description_copy (&font_entry->description); - tmp_list = tmp_list->next; - } -} - -static void -pango_x_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs) -{ - PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap; - ListFontsInfo info; - - if (!n_descs) - return; - - if (family) - { - PangoXFamilyEntry *entry = g_hash_table_lookup (xfontmap->families, family); - if (entry) - { - *n_descs = g_slist_length (entry->font_entries); - if (descs) - { - *descs = g_new (PangoFontDescription *, *n_descs); - - info.descs = *descs; - info.n_found = 0; - - list_fonts_foreach ((gpointer)family, (gpointer)entry, &info); - } - } - else - { - *n_descs = 0; - if (descs) - *descs = NULL; - } - } - else - { - *n_descs = xfontmap->n_fonts; - if (descs) - { - *descs = g_new (PangoFontDescription *, xfontmap->n_fonts); - - info.descs = *descs; - info.n_found = 0; - - g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info); - } - } + G_OBJECT_CLASS (font_map_parent_class)->finalize (object); } static void @@ -395,12 +331,12 @@ list_families_foreach (gpointer key, gpointer value, gpointer user_data) { GSList **list = user_data; - *list = g_slist_prepend (*list, key); + *list = g_slist_prepend (*list, value); } static void pango_x_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, + PangoFontFamily ***families, int *n_families) { GSList *family_list = NULL; @@ -418,12 +354,12 @@ pango_x_font_map_list_families (PangoFontMap *fontmap, { int i = 0; - *families = g_new (gchar *, *n_families); + *families = g_new (PangoFontFamily *, *n_families); tmp_list = family_list; while (tmp_list) { - (*families)[i] = g_strdup (tmp_list->data); + (*families)[i] = tmp_list->data; i++; tmp_list = tmp_list->next; } @@ -432,21 +368,21 @@ pango_x_font_map_list_families (PangoFontMap *fontmap, g_slist_free (family_list); } -static PangoXFamilyEntry * -pango_x_get_family_entry (PangoXFontMap *xfontmap, - const char *family_name) +static PangoXFamily * +pango_x_get_font_family (PangoXFontMap *xfontmap, + const char *family_name) { - PangoXFamilyEntry *family_entry = g_hash_table_lookup (xfontmap->families, family_name); - if (!family_entry) + PangoXFamily *font_family = g_hash_table_lookup (xfontmap->families, family_name); + if (!font_family) { - family_entry = g_new (PangoXFamilyEntry, 1); - family_entry->family_name = g_strdup (family_name); - family_entry->font_entries = NULL; + font_family = g_object_new (PANGO_X_TYPE_FAMILY, NULL); + font_family->family_name = g_strdup (family_name); + font_family->font_entries = NULL; - g_hash_table_insert (xfontmap->families, family_entry->family_name, family_entry); + g_hash_table_insert (xfontmap->families, font_family->family_name, font_family); } - return family_entry; + return font_family; } static PangoFont * @@ -454,58 +390,38 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, const PangoFontDescription *description) { PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap; - PangoXFamilyEntry *family_entry; + PangoXFamily *font_family; PangoFont *result = NULL; GSList *tmp_list; gchar *name; + gint size; g_return_val_if_fail (description != NULL, NULL); - g_return_val_if_fail (description->size > 0, NULL); - - name = g_strdup (description->family_name); - g_strdown (name); - family_entry = g_hash_table_lookup (xfontmap->families, name); - if (family_entry) + name = g_ascii_strdown (pango_font_description_get_family (description)); + size = pango_font_description_get_size (description); + + if (size <= 0) + return NULL; + + font_family = g_hash_table_lookup (xfontmap->families, name); + if (font_family) { - PangoXFontEntry *best_match = NULL; - int best_distance = G_MAXINT; + PangoXFace *best_match = NULL; - tmp_list = family_entry->font_entries; + tmp_list = font_family->font_entries; while (tmp_list) { - PangoXFontEntry *font_entry = tmp_list->data; + PangoXFace *font_entry = tmp_list->data; + + if (pango_font_description_better_match (description, + best_match ? best_match->description : NULL, + font_entry->description)) + best_match = font_entry; - if (font_entry->description.variant == description->variant && - font_entry->description.stretch == description->stretch) - { - if (font_entry->description.style == description->style) - { - int distance = abs(font_entry->description.weight - description->weight); - if (distance < best_distance) - { - best_match = font_entry; - best_distance = distance; - } - } - else if (font_entry->description.style != PANGO_STYLE_NORMAL && - description->style != PANGO_STYLE_NORMAL) - { - /* Equate oblique and italic, but with a big penalty - */ - int distance = PANGO_SCALE * 1000 + abs(font_entry->description.weight - description->weight); - - if (distance < best_distance) - { - best_match = font_entry; - best_distance = distance; - } - } - } - tmp_list = tmp_list->next; } - + if (best_match) { GSList *tmp_list = best_match->cached_fonts; @@ -513,7 +429,7 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, while (tmp_list) { PangoXFont *xfont = tmp_list->data; - if (xfont->size == description->size) + if (xfont->size == size) { result = (PangoFont *)xfont; @@ -528,10 +444,10 @@ pango_x_font_map_load_font (PangoFontMap *fontmap, if (!result) { - PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, description->size); + PangoXFont *xfont = pango_x_font_new (fontmap, best_match->xlfd, size); xfont->fontmap = fontmap; - xfont->entry = best_match; + xfont->xface = best_match; best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, xfont); result = (PangoFont *)xfont; @@ -815,7 +731,7 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, char **xlfds; int lineno = 0; int i; - PangoXFontEntry *font_entry = NULL; + PangoXFace *xface = NULL; infile = fopen (filename, "r"); if (infile) @@ -826,7 +742,11 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, while ((lines_read = pango_read_line (infile, line_buf))) { - PangoXFamilyEntry *family_entry; + PangoXFamily *font_family; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; const char *p = line_buf->str; @@ -838,34 +758,40 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, if (!pango_scan_string (&p, tmp_buf)) goto error; - font_entry = g_new (PangoXFontEntry, 1); - font_entry->xlfd = NULL; - font_entry->description.family_name = g_strdup (tmp_buf->str); - g_strdown (font_entry->description.family_name); + xface = g_object_new (PANGO_X_TYPE_FACE, NULL); + xface->xlfd = NULL; + xface->description = pango_font_description_new (); + + g_string_ascii_down (tmp_buf); + pango_font_description_set_family (xface->description, tmp_buf->str); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_style (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_style (tmp_buf->str, &style, TRUE)) goto error; + pango_font_description_set_style (xface->description, style); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_variant (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_variant (tmp_buf->str, &variant, TRUE)) goto error; - + pango_font_description_set_variant (xface->description, variant); + if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_weight (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_weight (tmp_buf->str, &weight, TRUE)) goto error; + pango_font_description_set_weight (xface->description, weight); if (!pango_scan_string (&p, tmp_buf)) goto error; - if (!pango_parse_stretch (tmp_buf->str, &font_entry->description, TRUE)) + if (!pango_parse_stretch (tmp_buf->str, &stretch, TRUE)) goto error; + pango_font_description_set_stretch (xface->description, stretch); if (!pango_scan_string (&p, tmp_buf)) goto error; @@ -887,19 +813,20 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, } } - font_entry->xlfd = g_strjoinv (",", xlfds); + xface->xlfd = g_strjoinv (",", xlfds); g_strfreev (xlfds); /* Insert the font entry into our structures */ - family_entry = pango_x_get_family_entry (xfontmap, font_entry->description.family_name); - family_entry->font_entries = g_slist_prepend (family_entry->font_entries, font_entry); + font_family = pango_x_get_font_family (xfontmap, + pango_font_description_get_family (xface->description)); + font_family->font_entries = g_slist_prepend (font_family->font_entries, xface); xfontmap->n_fonts++; - g_free (font_entry->description.family_name); - font_entry->description.family_name = family_entry->family_name; - font_entry->cached_fonts = NULL; - font_entry->coverage = NULL; + /* Save space by consolidating duplicated string */ + pango_font_description_set_family_static (xface->description, font_family->family_name); + xface->cached_fonts = NULL; + xface->coverage = NULL; } if (ferror (infile)) @@ -908,13 +835,13 @@ pango_x_font_map_read_alias_file (PangoXFontMap *xfontmap, goto out; error: - if (font_entry) + if (xface) { - if (font_entry->xlfd) - g_free (font_entry->xlfd); - if (font_entry->description.family_name) - g_free (font_entry->description.family_name); - g_free (font_entry); + if (xface->xlfd) + g_free (xface->xlfd); + if (xface->description) + pango_font_description_free (xface->description); + g_free (xface); } g_warning ("Error parsing line %d of alias file '%s'", lineno, filename); @@ -1040,8 +967,8 @@ pango_x_get_identifier (const char *fontname) */ static char* pango_x_get_xlfd_field (const char *fontname, - FontField field_num, - char *buffer) + FontField field_num, + char *buffer) { const char *t1, *t2; int countdown, len, num_dashes; @@ -1087,22 +1014,25 @@ pango_x_get_xlfd_field (const char *fontname, is created and inserted in alphabetical order in the table. */ static void pango_x_insert_font (PangoXFontMap *xfontmap, - const char *fontname) + const char *fontname) { - PangoFontDescription description; + PangoFontDescription *description; + char *family_name; + PangoStyle style; + PangoVariant variant; + PangoWeight weight; + PangoStretch stretch; char family_buffer[XLFD_MAX_FIELD_LEN]; char weight_buffer[XLFD_MAX_FIELD_LEN]; char slant_buffer[XLFD_MAX_FIELD_LEN]; char set_width_buffer[XLFD_MAX_FIELD_LEN]; GSList *tmp_list; - PangoXFamilyEntry *family_entry; - PangoXFontEntry *font_entry; + PangoXFamily *font_family; + PangoXFace *xface; PangoXSizeInfo *size_info; char *identifier; int i; - description.size = 0; - /* First insert the XLFD into the list of XLFDs for the "identifier" - which * is the 2-4th fields of the XLFD */ @@ -1123,20 +1053,18 @@ pango_x_insert_font (PangoXFontMap *xfontmap, /* Convert the XLFD into a PangoFontDescription */ - description.family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer); - g_strdown (description.family_name); - - if (!description.family_name) + family_name = pango_x_get_xlfd_field (fontname, XLFD_FAMILY, family_buffer); + if (!family_name) return; - - description.style = PANGO_STYLE_NORMAL; + + style = PANGO_STYLE_NORMAL; if (pango_x_get_xlfd_field (fontname, XLFD_SLANT, slant_buffer)) { for (i=0; ifont_entries; + tmp_list = font_family->font_entries; while (tmp_list) { - font_entry = tmp_list->data; + xface = tmp_list->data; - if (font_entry->description.style == description.style && - font_entry->description.variant == description.variant && - font_entry->description.weight == description.weight && - font_entry->description.stretch == description.stretch) + if (pango_font_description_get_style (xface->description) == style && + pango_font_description_get_weight (xface->description) == weight && + pango_font_description_get_stretch (xface->description) == stretch && + pango_font_description_get_variant (xface->description) == variant) return; tmp_list = tmp_list->next; } - font_entry = g_new (PangoXFontEntry, 1); - font_entry->description = description; - font_entry->description.family_name = family_entry->family_name; - font_entry->cached_fonts = NULL; - font_entry->coverage = NULL; + description = pango_font_description_new (); + pango_font_description_set_family_static (description, font_family->family_name); + pango_font_description_set_style (description, style); + pango_font_description_set_weight (description, weight); + pango_font_description_set_stretch (description, stretch); + pango_font_description_set_variant (description, variant); - font_entry->xlfd = g_strconcat ("-*-", + xface = g_object_new (PANGO_X_TYPE_FACE, NULL); + xface->description = description; + xface->cached_fonts = NULL; + xface->coverage = NULL; + + xface->xlfd = g_strconcat ("-*-", family_buffer, "-", weight_buffer, @@ -1209,7 +1143,7 @@ pango_x_insert_font (PangoXFontMap *xfontmap, "--*-*-*-*-*-*-*-*", NULL); - family_entry->font_entries = g_slist_append (family_entry->font_entries, font_entry); + font_family->font_entries = g_slist_append (font_family->font_entries, xface); xfontmap->n_fonts++; } @@ -1346,97 +1280,6 @@ free_coverages_foreach (gpointer key, pango_coverage_unref (value); } -PangoCoverage * -pango_x_font_entry_get_coverage (PangoXFontEntry *entry, - PangoFont *font, - PangoLanguage *language) -{ - PangoXFont *xfont; - PangoXFontMap *xfontmap = NULL; /* Quiet gcc */ - PangoCoverage *result = NULL; - GHashTable *coverage_hash; - Atom atom = None; - - if (entry) - { - if (entry->coverage) - { - pango_coverage_ref (entry->coverage); - return entry->coverage; - } - - xfont = (PangoXFont *)font; - - xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display); - if (entry->xlfd) - { - const char *lang_str = language ? pango_language_to_string (language) : "*"; - - char *str = g_strconcat (lang_str, "|", entry->xlfd, NULL); - result = pango_x_get_cached_coverage (xfontmap, str, &atom); - g_free (str); - } - } - - if (!result) - { - guint32 ch; - PangoMap *shape_map; - PangoCoverage *coverage; - PangoCoverageLevel font_level; - PangoMapEntry *map_entry; - - result = pango_coverage_new (); - - coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); - - shape_map = pango_x_get_shaper_map (language); - - for (ch = 0; ch < 65536; ch++) - { - map_entry = pango_map_get_entry (shape_map, ch); - if (map_entry->info) - { - coverage = g_hash_table_lookup (coverage_hash, map_entry->info->id); - if (!coverage) - { - PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch); - coverage = engine->get_coverage (font, language); - g_hash_table_insert (coverage_hash, map_entry->info->id, coverage); - } - - font_level = pango_coverage_get (coverage, ch); - if (font_level == PANGO_COVERAGE_EXACT && !map_entry->is_exact) - font_level = PANGO_COVERAGE_APPROXIMATE; - - if (font_level != PANGO_COVERAGE_NONE) - pango_coverage_set (result, ch, font_level); - } - } - - g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL); - g_hash_table_destroy (coverage_hash); - - if (atom) - pango_x_store_cached_coverage (xfontmap, atom, result); - } - - if (entry) - { - entry->coverage = result; - pango_coverage_ref (result); - } - - return result; -} - -void -pango_x_font_entry_remove (PangoXFontEntry *entry, - PangoFont *font) -{ - entry->cached_fonts = g_slist_remove (entry->cached_fonts, font); -} - PangoXFontCache * pango_x_font_map_get_font_cache (PangoFontMap *font_map) { @@ -1546,3 +1389,232 @@ pango_x_fontmap_name_from_atom (PangoFontMap *fontmap, return name2; } + +/* + * PangoXFace + */ + +static PangoFontDescription * +pango_x_face_describe (PangoFontFace *face) +{ + PangoXFace *xface = PANGO_X_FACE (face); + + return pango_font_description_copy (xface->description); +} + +static const char * +pango_x_face_get_face_name (PangoFontFace *face) +{ + PangoXFace *xface = PANGO_X_FACE (face); + + if (!xface->face_name) + { + PangoFontDescription *desc = pango_font_face_describe (face); + + pango_font_description_unset_fields (desc, + PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE); + + xface->face_name = pango_font_description_to_string (desc); + pango_font_description_free (desc); + } + + return xface->face_name; +} + +static void +pango_x_face_class_init (PangoFontFaceClass *class) +{ + class->describe = pango_x_face_describe; + class->get_face_name = pango_x_face_get_face_name; +} + +GType +pango_x_face_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (PangoFontFaceClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_x_face_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoXFace), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, + "PangoXFace", + &object_info, 0); + } + + return object_type; +} + +PangoCoverage * +pango_x_face_get_coverage (PangoXFace *xface, + PangoFont *font, + PangoLanguage *language) +{ + PangoXFont *xfont; + PangoXFontMap *xfontmap = NULL; /* Quiet gcc */ + PangoCoverage *result = NULL; + GHashTable *coverage_hash; + Atom atom = None; + + if (xface) + { + if (xface->coverage) + { + pango_coverage_ref (xface->coverage); + return xface->coverage; + } + + xfont = (PangoXFont *)font; + + xfontmap = (PangoXFontMap *)pango_x_font_map_for_display (xfont->display); + if (xface->xlfd) + { + const char *lang_str = language ? pango_language_to_string (language) : "*"; + + char *str = g_strconcat (lang_str, "|", xface->xlfd, NULL); + result = pango_x_get_cached_coverage (xfontmap, str, &atom); + g_free (str); + } + } + + if (!result) + { + guint32 ch; + PangoMap *shape_map; + PangoCoverage *coverage; + PangoCoverageLevel font_level; + PangoMapEntry *map_entry; + + result = pango_coverage_new (); + + coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); + + shape_map = pango_x_get_shaper_map (language); + + for (ch = 0; ch < 65536; ch++) + { + map_entry = pango_map_get_entry (shape_map, ch); + if (map_entry->info) + { + coverage = g_hash_table_lookup (coverage_hash, map_entry->info->id); + if (!coverage) + { + PangoEngineShape *engine = (PangoEngineShape *)pango_map_get_engine (shape_map, ch); + coverage = engine->get_coverage (font, language); + g_hash_table_insert (coverage_hash, map_entry->info->id, coverage); + } + + font_level = pango_coverage_get (coverage, ch); + if (font_level == PANGO_COVERAGE_EXACT && !map_entry->is_exact) + font_level = PANGO_COVERAGE_APPROXIMATE; + + if (font_level != PANGO_COVERAGE_NONE) + pango_coverage_set (result, ch, font_level); + } + } + + g_hash_table_foreach (coverage_hash, free_coverages_foreach, NULL); + g_hash_table_destroy (coverage_hash); + + if (atom) + pango_x_store_cached_coverage (xfontmap, atom, result); + } + + if (xface) + { + xface->coverage = result; + pango_coverage_ref (result); + } + + return result; +} + +void +pango_x_face_remove (PangoXFace *xface, + PangoFont *font) +{ + xface->cached_fonts = g_slist_remove (xface->cached_fonts, font); +} + +/* + * PangoXFontFamily + */ + +static void +pango_x_family_list_faces (PangoFontFamily *family, + PangoFontFace ***faces, + int *n_faces) +{ + PangoXFamily *xfamily = PANGO_X_FAMILY (family); + + *n_faces = g_slist_length (xfamily->font_entries); + if (faces) + { + GSList *tmp_list; + int i = 0; + + *faces = g_new (PangoFontFace *, *n_faces); + + tmp_list = xfamily->font_entries; + while (tmp_list) + { + (*faces)[i++] = tmp_list->data; + tmp_list = tmp_list->next; + } + } +} + +const char * +pango_x_family_get_name (PangoFontFamily *family) +{ + PangoXFamily *xfamily = PANGO_X_FAMILY (family); + + return xfamily->family_name; +} + +static void +pango_x_family_class_init (PangoFontFamilyClass *class) +{ + class->list_faces = pango_x_family_list_faces; + class->get_name = pango_x_family_get_name; +} + +GType +pango_x_family_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (PangoFontFamilyClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_x_family_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoXFamily), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, + "PangoXFamily", + &object_info, 0); + } + + return object_type; +} + diff --git a/pango/pangox-private.h b/pango/pangox-private.h index aa36d6f9..0fb12976 100644 --- a/pango/pangox-private.h +++ b/pango/pangox-private.h @@ -26,8 +26,8 @@ #include "pangox.h" #include "pangox-private.h" -typedef struct _PangoXFont PangoXFont; -typedef struct _PangoXFontEntry PangoXFontEntry; +typedef struct _PangoXFace PangoXFace; +typedef struct _PangoXFont PangoXFont; typedef struct _PangoXSubfontInfo PangoXSubfontInfo; struct _PangoXFont @@ -57,7 +57,7 @@ struct _PangoXFont */ gboolean in_cache; - PangoXFontEntry *entry; /* Used to remove cached fonts */ + PangoXFace *xface; /* Used to remove cached fonts */ }; @@ -103,10 +103,10 @@ char * pango_x_make_matching_xlfd (PangoFontMap *fontmap, char *xlfd, const char *charset, int size); -PangoCoverage *pango_x_font_entry_get_coverage (PangoXFontEntry *entry, +PangoCoverage *pango_x_face_get_coverage (PangoXFace *xface, PangoFont *font, PangoLanguage *language); -void pango_x_font_entry_remove (PangoXFontEntry *entry, +void pango_x_face_remove (PangoXFace *xface, PangoFont *font); Display * pango_x_fontmap_get_display (PangoFontMap *fontmap); @@ -120,7 +120,4 @@ Atom pango_x_fontmap_atom_from_name (PangoFontMap *fontmap, const char *pango_x_fontmap_name_from_atom (PangoFontMap *fontmap, Atom atom); -PangoGlyph pango_x_font_get_unknown_glyph (PangoFont *font, - gunichar wc); - #endif /* __PANGOX_PRIVATE_H__ */ diff --git a/pango/pangox.c b/pango/pangox.c index 20b244de..26a0189e 100644 --- a/pango/pangox.c +++ b/pango/pangox.c @@ -117,7 +117,7 @@ struct _PangoXSubfontInfo struct _PangoXMetricsInfo { const char *sample_str; - PangoFontMetrics metrics; + PangoFontMetrics *metrics; }; struct _PangoXContextInfo @@ -166,9 +166,8 @@ static void pango_x_font_get_glyph_extents (PangoFont *f PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); -static void pango_x_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics); +static PangoFontMetrics * pango_x_font_get_metrics (PangoFont *font, + PangoLanguage *language); static PangoXSubfontInfo * pango_x_find_subfont (PangoFont *font, PangoXSubfont subfont_index); @@ -346,7 +345,7 @@ pango_x_font_init (PangoXFont *xfont) xfont->metrics_by_lang = NULL; xfont->size = -1; - xfont->entry = NULL; + xfont->xface = NULL; } static void @@ -452,18 +451,16 @@ pango_x_render (Display *display, if (glyphs->glyphs[i].glyph & PANGO_X_UNKNOWN_FLAG) { + PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL); int x1, y1, x2, y2; /* rectangle the character should go inside. */ int baseline; - PangoFontMetrics metrics; gunichar wc; - pango_font_get_metrics (font, NULL, &metrics); - x1 = x + (x_off + glyphs->glyphs[i].geometry.x_offset) / PANGO_SCALE; - y1 = y + (glyphs->glyphs[i].geometry.y_offset - metrics.ascent) / PANGO_SCALE; + y1 = y + (glyphs->glyphs[i].geometry.y_offset - metrics->ascent) / PANGO_SCALE; x2 = x1 + glyphs->glyphs[i].geometry.width / PANGO_SCALE; - y2 = y1 + (metrics.ascent + metrics.descent) / PANGO_SCALE; - baseline = y1 + metrics.ascent / PANGO_SCALE; + y2 = y1 + (metrics->ascent + metrics->descent) / PANGO_SCALE; + baseline = y1 + metrics->ascent / PANGO_SCALE; wc = glyphs->glyphs[i].glyph & (~PANGO_X_UNKNOWN_FLAG); @@ -533,6 +530,8 @@ pango_x_render (Display *display, break; } + + pango_font_metrics_unref (metrics); } else if (glyphs->glyphs[i].glyph) { @@ -592,29 +591,29 @@ pango_x_font_get_glyph_extents (PangoFont *font, case 0x2029: /* Paragraph separator */ { /* Size of carriage-return thingy */ - PangoFontMetrics metrics; + PangoFontMetrics *metrics = pango_font_get_metrics (font, NULL); int w; - pango_font_get_metrics (font, NULL, &metrics); - #define MAGIC_FACTOR 1.75 - w = metrics.approximate_char_width * MAGIC_FACTOR; + w = metrics->approximate_char_width * MAGIC_FACTOR; if (ink_rect) { ink_rect->x = 0; ink_rect->width = w; - ink_rect->y = - metrics.ascent; - ink_rect->height = metrics.ascent + metrics.descent; + ink_rect->y = - metrics->ascent; + ink_rect->height = metrics->ascent + metrics->descent; } if (logical_rect) { logical_rect->x = 0; logical_rect->width = w; - logical_rect->y = - metrics.ascent; - logical_rect->height = metrics.ascent + metrics.descent; + logical_rect->y = - metrics->ascent; + logical_rect->height = metrics->ascent + metrics->descent; } + + pango_font_metrics_unref (metrics); } break; @@ -855,10 +854,9 @@ get_font_metrics_from_string (PangoFont *font, g_free (embedding_levels); } -static void +static PangoFontMetrics * pango_x_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { PangoXMetricsInfo *info = NULL; /* Quiet gcc */ PangoXFont *xfont = (PangoXFont *)font; @@ -885,10 +883,11 @@ pango_x_font_get_metrics (PangoFont *font, info = g_new (PangoXMetricsInfo, 1); info->sample_str = sample_str; + info->metrics = pango_font_metrics_new (); xfont->metrics_by_lang = g_slist_prepend (xfont->metrics_by_lang, info); - get_font_metrics_from_string (font, language, sample_str, &info->metrics); + get_font_metrics_from_string (font, language, sample_str, info->metrics); /* This is sort of a sledgehammer solution, but we cache this * stuff so not a huge deal hopefully. Get the avg. width of the @@ -901,14 +900,13 @@ pango_x_font_get_metrics (PangoFont *font, pango_layout_get_extents (layout, NULL, &extents); - info->metrics.approximate_digit_width = extents.width / 10.0; + info->metrics->approximate_digit_width = extents.width / 10.0; g_object_unref (G_OBJECT (layout)); g_object_unref (G_OBJECT (context)); } - *metrics = info->metrics; - return; + return pango_font_metrics_ref (info->metrics); } /* Compare the tail of a to b */ @@ -1196,6 +1194,13 @@ free_sets_foreach (gpointer key, gpointer value, gpointer data) pango_int_set_destroy (value); } +static void +free_metrics_info (PangoXMetricsInfo *info) +{ + pango_font_metrics_unref (info->metrics); + g_free (info); +} + static void pango_x_font_finalize (GObject *object) { @@ -1235,11 +1240,11 @@ pango_x_font_finalize (GObject *object) g_hash_table_foreach (xfont->subfonts_by_charset, subfonts_foreach, NULL); g_hash_table_destroy (xfont->subfonts_by_charset); - g_slist_foreach (xfont->metrics_by_lang, (GFunc)g_free, NULL); + g_slist_foreach (xfont->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (xfont->metrics_by_lang); - if (xfont->entry) - pango_x_font_entry_remove (xfont->entry, (PangoFont *)xfont); + if (xfont->xface) + pango_x_face_remove (xfont->xface, (PangoFont *)xfont); g_object_unref (G_OBJECT (xfont->fontmap)); @@ -1276,7 +1281,7 @@ pango_x_font_get_coverage (PangoFont *font, { PangoXFont *xfont = (PangoXFont *)font; - return pango_x_font_entry_get_coverage (xfont->entry, font, language); + return pango_x_face_get_coverage (xfont->xface, font, language); } static PangoEngineShape * diff --git a/pango/pangox.h b/pango/pangox.h index a56fda91..20d10863 100644 --- a/pango/pangox.h +++ b/pango/pangox.h @@ -26,9 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #include @@ -83,6 +81,10 @@ gboolean pango_x_has_glyph (PangoFont *font, PangoGlyph glyph); PangoGlyph pango_x_get_unknown_glyph (PangoFont *font); +#ifdef PANGO_ENABLE_ENGINE +PangoGlyph pango_x_font_get_unknown_glyph (PangoFont *font, + gunichar wc); +#endif /* PANGO_ENABLE_ENGINE */ /* API for libraries that want to use PangoX mixed with classic X fonts. */ @@ -120,10 +122,6 @@ gboolean pango_x_apply_ligatures (PangoFont *font, int *n_glyphs, int **clusters); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __PANGOX_H__ */ diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c index 5c7a656e..a00cc7e5 100644 --- a/pango/pangoxft-font.c +++ b/pango/pangoxft-font.c @@ -54,9 +54,8 @@ static void pango_xft_font_get_glyph_extents (PangoFont PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect); -static void pango_xft_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics); +static PangoFontMetrics * pango_xft_font_get_metrics (PangoFont *font, + PangoLanguage *language); GType @@ -143,7 +142,7 @@ get_mini_font (PangoFont *font) if (!xfont->mini_font) { Display *display; - PangoFontDescription desc; + PangoFontDescription *desc = pango_font_description_new (); int i; int width = 0, height = 0; XGlyphInfo extents; @@ -151,15 +150,14 @@ get_mini_font (PangoFont *font) FT_Face face; _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL); + + pango_font_description_set_family_static (desc, "monospace"); + pango_font_description_set_size (desc, + 0.5 * pango_font_description_get_size (xfont->description)); - desc.family_name = "monospace"; - desc.style = PANGO_STYLE_NORMAL; - desc.variant = PANGO_VARIANT_NORMAL; - desc.weight = PANGO_WEIGHT_NORMAL; - - desc.size = 0.5 * xfont->description->size; + xfont->mini_font = pango_font_map_load_font (xfont->fontmap, desc); + pango_font_description_free (desc); - xfont->mini_font = pango_font_map_load_font (xfont->fontmap, &desc); mini_xft = ((PangoXftFont *)xfont->mini_font)->xft_font; face = pango_xft_font_get_face (xfont->mini_font); @@ -280,17 +278,19 @@ pango_xft_render (XftDraw *draw, } } -static void +static PangoFontMetrics * pango_xft_font_get_metrics (PangoFont *font, - PangoLanguage *language, - PangoFontMetrics *metrics) + PangoLanguage *language) { PangoXftFont *xfont = (PangoXftFont *)font; + PangoFontMetrics *metrics = pango_font_metrics_new (); metrics->ascent = PANGO_SCALE * xfont->xft_font->ascent; metrics->descent = PANGO_SCALE * xfont->xft_font->descent; metrics->approximate_digit_width = PANGO_SCALE * xfont->xft_font->max_advance_width; metrics->approximate_char_width = PANGO_SCALE * xfont->xft_font->max_advance_width; + + return metrics; } static void @@ -344,6 +344,7 @@ pango_xft_font_get_coverage (PangoFont *font, PangoLanguage *language) { PangoXftFont *xfont = (PangoXftFont *)font; + const gchar *family = pango_font_description_get_family (xfont->description); FT_Face face; PangoCoverage *coverage; Display *display; @@ -351,8 +352,7 @@ pango_xft_font_get_coverage (PangoFont *font, _pango_xft_font_map_get_info (xfont->fontmap, &display, NULL); - coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, - xfont->description->family_name); + coverage = _pango_xft_font_map_get_coverage (xfont->fontmap, family); if (coverage) return pango_coverage_ref (coverage); @@ -370,7 +370,7 @@ pango_xft_font_get_coverage (PangoFont *font, pango_coverage_set (coverage, i, PANGO_COVERAGE_EXACT); } - _pango_xft_font_map_set_coverage (xfont->fontmap, xfont->description->family_name, coverage); + _pango_xft_font_map_set_coverage (xfont->fontmap, family, coverage); return coverage; } diff --git a/pango/pangoxft-fontmap.c b/pango/pangoxft-fontmap.c index c9f044a6..a63f969a 100644 --- a/pango/pangoxft-fontmap.c +++ b/pango/pangoxft-fontmap.c @@ -26,18 +26,16 @@ #include "X11/Xft/XftFreetype.h" -#define PANGO_TYPE_XFT_FONT_MAP (pango_xft_font_map_get_type ()) -#define PANGO_XFT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMap)) -#define PANGO_XFT_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMapClass)) -#define PANGO_XFT_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_XFT_FONT_MAP)) -#define PANGO_XFT_IS_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_XFT_FONT_MAP)) -#define PANGO_XFT_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMapClass)) - /* Number of freed fonts */ #define MAX_FREED_FONTS 16 typedef struct _PangoXftFontMap PangoXftFontMap; -typedef struct _PangoXftFontMapClass PangoXftFontMapClass; +typedef struct _PangoXftFamily PangoXftFamily; +typedef struct _PangoXftFace PangoXftFace; + +#define PANGO_TYPE_XFT_FONT_MAP (pango_xft_font_map_get_type ()) +#define PANGO_XFT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_XFT_FONT_MAP, PangoXftFontMap)) +#define PANGO_XFT_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_XFT_FONT_MAP)) struct _PangoXftFontMap { @@ -47,29 +45,52 @@ struct _PangoXftFontMap GHashTable *coverage_hash; GQueue *freed_fonts; + PangoXftFamily **families; + int n_families; /* -1 == uninitialized */ + Display *display; int screen; }; -struct _PangoXftFontMapClass +#define PANGO_XFT_TYPE_FAMILY (pango_xft_family_get_type ()) +#define PANGO_XFT_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_XFT_TYPE_FAMILY, PangoXftFamily)) +#define PANGO_XFT_IS_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_XFT_TYPE_FAMILY)) + +struct _PangoXftFamily +{ + PangoFontFamily parent_instance; + + PangoXftFontMap *fontmap; + char *family_name; + + PangoXftFace **faces; + int n_faces; /* -1 == uninitialized */ +}; + +#define PANGO_XFT_TYPE_FACE (pango_xft_face_get_type ()) +#define PANGO_XFT_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_XFT_TYPE_FACE, PangoXftFace)) +#define PANGO_XFT_IS_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_XFT_TYPE_FACE)) + +struct _PangoXftFace { - PangoFontMapClass parent_class; + PangoFontFace parent_instance; + + PangoXftFamily *family; + char *style; }; static GType pango_xft_font_map_get_type (void); -static void pango_xft_font_map_init (PangoXftFontMap *fontmap); -static void pango_xft_font_map_class_init (PangoXftFontMapClass *class); +GType pango_xft_family_get_type (void); +GType pango_xft_face_get_type (void); +static void pango_xft_font_map_init (PangoXftFontMap *fontmap); +static void pango_xft_font_map_class_init (PangoFontMapClass *class); static void pango_xft_font_map_finalize (GObject *object); static PangoFont *pango_xft_font_map_load_font (PangoFontMap *fontmap, - const PangoFontDescription *description); -static void pango_xft_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs); + const PangoFontDescription *description); static void pango_xft_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, - int *n_families); + PangoFontFamily ***families, + int *n_families); static void pango_xft_font_map_cache_clear (PangoXftFontMap *xfontmap); static void pango_xft_font_map_cache_remove (PangoFontMap *fontmap, @@ -86,7 +107,7 @@ pango_xft_font_map_get_type (void) { static const GTypeInfo object_info = { - sizeof (PangoXftFontMapClass), + sizeof (PangoFontMapClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) pango_xft_font_map_class_init, @@ -108,41 +129,23 @@ pango_xft_font_map_get_type (void) static void pango_xft_font_map_init (PangoXftFontMap *xfontmap) { + xfontmap->n_families = -1; } static void -pango_xft_font_map_class_init (PangoXftFontMapClass *class) +pango_xft_font_map_class_init (PangoFontMapClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); - PangoFontMapClass *font_map_class = PANGO_FONT_MAP_CLASS (class); parent_class = g_type_class_peek_parent (class); object_class->finalize = pango_xft_font_map_finalize; - font_map_class->load_font = pango_xft_font_map_load_font; - font_map_class->list_fonts = pango_xft_font_map_list_fonts; - font_map_class->list_families = pango_xft_font_map_list_families; + class->load_font = pango_xft_font_map_load_font; + class->list_families = pango_xft_font_map_list_families; } static GSList *fontmaps = NULL; -static guint -font_description_hash (const PangoFontDescription *desc) -{ - guint hash = 0; - - if (desc->family_name) - hash = g_str_hash (desc->family_name); - - hash ^= desc->size; - hash ^= desc->style << 16; - hash ^= desc->variant << 18; - hash ^= desc->weight << 16; - hash ^= desc->stretch << 26; - - return hash; -} - static PangoFontMap * pango_xft_get_font_map (Display *display, int screen) @@ -169,7 +172,7 @@ pango_xft_get_font_map (Display *display, xfontmap->display = display; xfontmap->screen = screen; - xfontmap->font_hash = g_hash_table_new ((GHashFunc)font_description_hash, + xfontmap->font_hash = g_hash_table_new ((GHashFunc)pango_font_description_hash, (GEqualFunc)pango_font_description_equal); xfontmap->coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); xfontmap->freed_fonts = g_queue_new (); @@ -246,124 +249,26 @@ _pango_xft_font_map_remove (PangoFontMap *fontmap, g_hash_table_remove (xfontmap->font_hash, xfont->description); } -static PangoFontDescription * -font_desc_from_pattern (XftPattern *pattern) -{ - PangoFontDescription *desc; - char *s; - int i; - - desc = g_new (PangoFontDescription, 1); - - g_assert (XftPatternGetString (pattern, XFT_FAMILY, 0, &s) == XftResultMatch); - - desc->family_name = g_strdup (s); - - if (XftPatternGetInteger (pattern, XFT_SLANT, 0, &i) == XftResultMatch) - { - if (i == XFT_SLANT_ROMAN) - desc->style = PANGO_STYLE_NORMAL; - else if (i == XFT_SLANT_OBLIQUE) - desc->style = PANGO_STYLE_OBLIQUE; - else - desc->style = PANGO_STYLE_ITALIC; - } - else - desc->style = PANGO_STYLE_NORMAL; - - if (XftPatternGetInteger (pattern, XFT_WEIGHT, 0, &i) == XftResultMatch) - { - if (i < XFT_WEIGHT_LIGHT) - desc->weight = PANGO_WEIGHT_ULTRALIGHT; - else if (i < (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2) - desc->weight = PANGO_WEIGHT_LIGHT; - else if (i < (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_DEMIBOLD) / 2) - desc->weight = PANGO_WEIGHT_NORMAL; - else if (i < (XFT_WEIGHT_DEMIBOLD + XFT_WEIGHT_BOLD) / 2) - desc->weight = 600; - else if (i < (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2) - desc->weight = PANGO_WEIGHT_BOLD; - else - desc->weight = PANGO_WEIGHT_ULTRABOLD; - } - - desc->variant = PANGO_VARIANT_NORMAL; - desc->stretch = PANGO_STRETCH_NORMAL; - desc->size = -1; - - return desc; -} - - -static void -pango_xft_font_map_list_fonts (PangoFontMap *fontmap, - const gchar *family, - PangoFontDescription ***descs, - int *n_descs) -{ - PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap); - XftFontSet *fontset; - - if (family) - fontset = XftListFonts (xfontmap->display, xfontmap->screen, - XFT_ENCODING, XftTypeString, "iso10646-1", - XFT_FAMILY, XftTypeString, family, - XFT_CORE, XftTypeBool, False, - NULL, - XFT_FAMILY, - XFT_STYLE, - XFT_WEIGHT, - XFT_SLANT, - NULL); - else - fontset = XftListFonts (xfontmap->display, xfontmap->screen, - XFT_ENCODING, XftTypeString, "iso10646-1", - XFT_CORE, XftTypeBool, False, - NULL, - XFT_FAMILY, - XFT_STYLE, - XFT_WEIGHT, - XFT_SLANT, - NULL); - - if (n_descs) - *n_descs = fontset->nfont; - - if (descs) - { - gint i; - - *descs = g_new (PangoFontDescription *, fontset->nfont); - - for (i = 0; i < fontset->nfont; i++) - (*descs)[i] = font_desc_from_pattern (fontset->fonts[i]); - } - - XftFontSetDestroy (fontset); -} - static void pango_xft_font_map_list_families (PangoFontMap *fontmap, - gchar ***families, + PangoFontFamily ***families, int *n_families) { PangoXftFontMap *xfontmap = PANGO_XFT_FONT_MAP (fontmap); XftFontSet *fontset; int i; - fontset = XftListFonts (xfontmap->display, xfontmap->screen, - XFT_CORE, XftTypeBool, False, - XFT_ENCODING, XftTypeString, "iso10646-1", - NULL, - XFT_FAMILY, - NULL); - - if (n_families) - *n_families = fontset->nfont; - - if (families) + if (xfontmap->n_families < 0) { - *families = g_new (gchar *, fontset->nfont); + fontset = XftListFonts (xfontmap->display, xfontmap->screen, + XFT_CORE, XftTypeBool, False, + XFT_ENCODING, XftTypeString, "iso10646-1", + NULL, + XFT_FAMILY, + NULL); + + xfontmap->n_families = fontset->nfont; + xfontmap->families = g_new (PangoXftFamily *, xfontmap->n_families); for (i = 0; i < fontset->nfont; i++) { @@ -372,12 +277,20 @@ pango_xft_font_map_list_families (PangoFontMap *fontmap, res = XftPatternGetString (fontset->fonts[i], XFT_FAMILY, 0, &s); g_assert (res == XftResultMatch); - - (*families)[i] = g_strdup (s); + + xfontmap->families[i] = g_object_new (PANGO_XFT_TYPE_FAMILY, NULL); + xfontmap->families[i]->family_name = g_strdup (s); + xfontmap->families[i]->fontmap = xfontmap; } - } - XftFontSetDestroy (fontset); + XftFontSetDestroy (fontset); + } + + if (n_families) + *n_families = xfontmap->n_families; + + if (families) + *families = g_memdup (xfontmap->families, xfontmap->n_families * sizeof (PangoFontFamily *)); } static PangoFont * @@ -386,7 +299,9 @@ pango_xft_font_map_load_font (PangoFontMap *fontmap, { PangoXftFontMap *xfontmap = (PangoXftFontMap *)fontmap; PangoXftFont *font; + PangoStyle pango_style; int slant; + PangoWeight pango_weight; int weight; XftFont *xft_font; @@ -400,20 +315,24 @@ pango_xft_font_map_load_font (PangoFontMap *fontmap, return (PangoFont *)g_object_ref (G_OBJECT (font)); } - if (description->style == PANGO_STYLE_ITALIC) + pango_style = pango_font_description_get_style (description); + + if (pango_style == PANGO_STYLE_ITALIC) slant = XFT_SLANT_ITALIC; - else if (description->style == PANGO_STYLE_OBLIQUE) + else if (pango_style == PANGO_STYLE_OBLIQUE) slant = XFT_SLANT_OBLIQUE; else slant = XFT_SLANT_ROMAN; - if (description->weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2) + pango_weight = pango_font_description_get_weight (description); + + if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2) weight = XFT_WEIGHT_LIGHT; - else if (description->weight < (PANGO_WEIGHT_NORMAL + 600) / 2) + else if (pango_weight < (PANGO_WEIGHT_NORMAL + 600) / 2) weight = XFT_WEIGHT_MEDIUM; - else if (description->weight < (600 + PANGO_WEIGHT_BOLD) / 2) + else if (pango_weight < (600 + PANGO_WEIGHT_BOLD) / 2) weight = XFT_WEIGHT_DEMIBOLD; - else if (description->weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2) + else if (pango_weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2) weight = XFT_WEIGHT_BOLD; else weight = XFT_WEIGHT_BLACK; @@ -424,10 +343,10 @@ pango_xft_font_map_load_font (PangoFontMap *fontmap, xft_font = XftFontOpen (xfontmap->display, xfontmap->screen, XFT_ENCODING, XftTypeString, "glyphs-fontspecific", XFT_CORE, XftTypeBool, False, - XFT_FAMILY, XftTypeString, description->family_name, + XFT_FAMILY, XftTypeString, pango_font_description_get_family (description), XFT_WEIGHT, XftTypeInteger, weight, XFT_SLANT, XftTypeInteger, slant, - XFT_SIZE, XftTypeDouble, (double)description->size/PANGO_SCALE, + XFT_SIZE, XftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE, NULL); if (xft_font) @@ -547,3 +466,237 @@ _pango_xft_font_map_get_info (PangoFontMap *fontmap, *screen = xfontmap->screen; } + + +/* + * PangoXftFace + */ + +static PangoFontDescription * +font_desc_from_pattern (XftPattern *pattern) +{ + PangoFontDescription *desc; + PangoStyle style; + PangoWeight weight; + + char *s; + int i; + + desc = pango_font_description_new (); + + g_assert (XftPatternGetString (pattern, XFT_FAMILY, 0, &s) == XftResultMatch); + + pango_font_description_set_family (desc, s); + + if (XftPatternGetInteger (pattern, XFT_SLANT, 0, &i) == XftResultMatch) + { + if (i == XFT_SLANT_ROMAN) + style = PANGO_STYLE_NORMAL; + else if (i == XFT_SLANT_OBLIQUE) + style = PANGO_STYLE_OBLIQUE; + else + style = PANGO_STYLE_ITALIC; + } + else + style = PANGO_STYLE_NORMAL; + + pango_font_description_set_style (desc, style); + + if (XftPatternGetInteger (pattern, XFT_WEIGHT, 0, &i) == XftResultMatch) + { + if (i < XFT_WEIGHT_LIGHT) + weight = PANGO_WEIGHT_ULTRALIGHT; + else if (i < (XFT_WEIGHT_LIGHT + XFT_WEIGHT_MEDIUM) / 2) + weight = PANGO_WEIGHT_LIGHT; + else if (i < (XFT_WEIGHT_MEDIUM + XFT_WEIGHT_DEMIBOLD) / 2) + weight = PANGO_WEIGHT_NORMAL; + else if (i < (XFT_WEIGHT_DEMIBOLD + XFT_WEIGHT_BOLD) / 2) + weight = 600; + else if (i < (XFT_WEIGHT_BOLD + XFT_WEIGHT_BLACK) / 2) + weight = PANGO_WEIGHT_BOLD; + else + weight = PANGO_WEIGHT_ULTRABOLD; + } + else + weight = PANGO_WEIGHT_NORMAL; + + pango_font_description_set_weight (desc, weight); + + pango_font_description_set_variant (desc, PANGO_VARIANT_NORMAL); + pango_font_description_set_stretch (desc, PANGO_STRETCH_NORMAL); + + return desc; +} + +static PangoFontDescription * +pango_xft_face_describe (PangoFontFace *face) +{ + PangoXftFace *xface = PANGO_XFT_FACE (face); + PangoXftFamily *xfamily = xface->family; + PangoXftFontMap *xfontmap = xfamily->fontmap; + PangoFontDescription *desc = NULL; + XftResult res; + XftPattern *match_pattern; + XftPattern *result_pattern; + + match_pattern = XftPatternBuild (NULL, + XFT_ENCODING, XftTypeString, "iso10646-1", + XFT_FAMILY, XftTypeString, xfamily->family_name, + XFT_CORE, XftTypeBool, False, + XFT_STYLE, XftTypeString, xface->style, + NULL); + g_assert (match_pattern); + + result_pattern = XftFontMatch (xfontmap->display, xfontmap->screen, match_pattern, &res); + if (result_pattern) + { + desc = font_desc_from_pattern (result_pattern); + XftPatternDestroy (result_pattern); + } + + XftPatternDestroy (match_pattern); + + return desc; +} + +static const char * +pango_xft_face_get_face_name (PangoFontFace *face) +{ + PangoXftFace *xface = PANGO_XFT_FACE (face); + + return xface->style; +} + +static void +pango_xft_face_class_init (PangoFontFaceClass *class) +{ + class->describe = pango_xft_face_describe; + class->get_face_name = pango_xft_face_get_face_name; +} + +GType +pango_xft_face_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (PangoFontFaceClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_xft_face_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoXftFace), + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + }; + + object_type = g_type_register_static (PANGO_TYPE_FONT_FACE, + "PangoXftFace", + &object_info, 0); + } + + return object_type; +} + +/* + * PangoXFontFamily + */ +static void +pango_xft_family_list_faces (PangoFontFamily *family, + PangoFontFace ***faces, + int *n_faces) +{ + PangoXftFamily *xfamily = PANGO_XFT_FAMILY (family); + PangoXftFontMap *xfontmap = xfamily->fontmap; + + if (xfamily->n_faces < 0) + { + XftFontSet *fontset; + int i; + + fontset = XftListFonts (xfontmap->display, xfontmap->screen, + XFT_ENCODING, XftTypeString, "iso10646-1", + XFT_FAMILY, XftTypeString, xfamily->family_name, + XFT_CORE, XftTypeBool, False, + NULL, + XFT_STYLE, + NULL); + + xfamily->n_faces = fontset->nfont; + xfamily->faces = g_new (PangoXftFace *, xfamily->n_faces); + + for (i = 0; i < fontset->nfont; i++) + { + char *s; + XftResult res; + + res = XftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s); + g_assert (res == XftResultMatch); + + xfamily->faces[i] = g_object_new (PANGO_XFT_TYPE_FACE, NULL); + xfamily->faces[i]->style = g_strdup (s); + xfamily->faces[i]->family = xfamily; + } + + XftFontSetDestroy (fontset); + } + + if (n_faces) + *n_faces = xfamily->n_faces; + + if (faces) + *faces = g_memdup (xfamily->faces, xfamily->n_faces * sizeof (PangoFontFace *)); +} + +const char * +pango_xft_family_get_name (PangoFontFamily *family) +{ + PangoXftFamily *xfamily = PANGO_XFT_FAMILY (family); + + return xfamily->family_name; +} + +static void +pango_xft_family_class_init (PangoFontFamilyClass *class) +{ + class->list_faces = pango_xft_family_list_faces; + class->get_name = pango_xft_family_get_name; +} + +void +pango_xft_family_init (PangoXftFamily *xfamily) +{ + xfamily->n_faces = -1; +} + +GType +pango_xft_family_get_type (void) +{ + static GType object_type = 0; + + if (!object_type) + { + static const GTypeInfo object_info = + { + sizeof (PangoFontFamilyClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) pango_xft_family_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof (PangoXftFamily), + 0, /* n_preallocs */ + (GInstanceInitFunc) pango_xft_family_init, + }; + + object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY, + "PangoXftFamily", + &object_info, 0); + } + + return object_type; +} diff --git a/pango/pangoxft-private.h b/pango/pangoxft-private.h index 00ad89fc..f7e54382 100644 --- a/pango/pangoxft-private.h +++ b/pango/pangoxft-private.h @@ -19,11 +19,14 @@ * Boston, MA 02111-1307, USA. */ -#include - #ifndef __PANGOXFT_PRIVATE_H__ #define __PANGOXFT_PRIVATE_H__ +#include +#include + +G_BEGIN_DECLS + typedef struct _PangoXftFont PangoXftFont; struct _PangoXftFont @@ -61,4 +64,6 @@ void _pango_xft_font_map_get_info (PangoFontMap *fo Display **display, int *screen); +G_END_DECLS + #endif /* __PANGOXFT_PRIVATE_H__ */ diff --git a/pango/pangoxft.h b/pango/pangoxft.h index b8b8d649..3e1f16aa 100644 --- a/pango/pangoxft.h +++ b/pango/pangoxft.h @@ -26,9 +26,7 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ +G_BEGIN_DECLS #include #include @@ -54,16 +52,15 @@ GType pango_xft_font_get_type (void); /* For shape engines */ +#ifdef PANGO_ENABLE_ENGINE XftFont * pango_xft_font_get_font (PangoFont *font); FT_Face pango_xft_font_get_face (PangoFont *font); -PangoOTInfo * pango_xft_font_get_ot_info (PangoFont *font); Display * pango_xft_font_get_display (PangoFont *font); PangoGlyph pango_xft_font_get_unknown_glyph (PangoFont *font, gunichar wc); +PangoOTInfo * pango_xft_font_get_ot_info (PangoFont *font); +#endif /* PANGO_ENABLE_ENGINE */ -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __PANGOXFT_H__ */ -- cgit v1.2.1