diff options
author | Owen Taylor <otaylor@redhat.com> | 2001-09-18 20:05:20 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2001-09-18 20:05:20 +0000 |
commit | a49e070d24242c0297e6325587c4bc135e13e26c (patch) | |
tree | 0510d066cc185e9d0b1b736736da5266d259878e /pango/pangoft2-fontmap.c | |
parent | 39f3626e34e0522e0bdec591f6c0334307d39625 (diff) | |
download | pango-a49e070d24242c0297e6325587c4bc135e13e26c.tar.gz |
Up to 0.19.
Tue Sep 18 15:47:08 2001 Owen Taylor <otaylor@redhat.com>
* 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.
Diffstat (limited to 'pango/pangoft2-fontmap.c')
-rw-r--r-- | pango/pangoft2-fontmap.c | 808 |
1 files changed, 427 insertions, 381 deletions
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; } |