From 0766534429b5830716e782418179ea63f8f1f65d Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Sun, 18 Nov 2001 16:06:02 +0000 Subject: Check for LEX and YACC. This will be made optional later, with the build 2001-11-17 Alexander Larsson * configure.in: Check for LEX and YACC. This will be made optional later, with the build sources checked in to cvs. Generate pango/mini-xft/Makefile * modules/basic/basic-ft2.c: Use the new pangoft2 API. * pango/Makefile.am: Build mini-xft. Add new files. * pango/pango-context.[ch]: Support only one fontmap per context. Use pango_font_map_load_fontset() and PangoFontset instead of internal fontset. * pango/pango-fontmap.[ch]: New virtual function pango_font_map_load_fontset() and default implementation that uses pango_font_map_load_font(). * pango/pango-utils.[ch] (pango_lookup_aliases): Utility function for looking up aliases. This can be used by backend that has no backend specific aliases. * pango/pangoft2-fontcache.c: Removed file. * pango/pangoft2-fontmap.c: * pango/pangoft2-private.h: * pango/pangoft2.c: * pango/pangoft2.h: Major rewrite. Doesn't handle fontsets. Uses mini-xft so that it will always match the PangoXft backend. Simplified the public API. * pango/pangowin32.c: * pango/pangox.c: pango_context_add_font_map -> pango_context_set_font_map * pango/pangoxft-font.c: * pango/pangoxft-fontmap.c: * pango/pangoxft-private.h: New code to handle fontsets. * pango/mini-xft/*: Mini version of libXft from XFree86 in order to have the pangoFT2 and pangXft backends have same config files and generate the same fonts. --- pango/pangoft2-fontmap.c | 1313 +++++++++++++++++----------------------------- 1 file changed, 475 insertions(+), 838 deletions(-) (limited to 'pango/pangoft2-fontmap.c') diff --git a/pango/pangoft2-fontmap.c b/pango/pangoft2-fontmap.c index 6690da38..51039df5 100644 --- a/pango/pangoft2-fontmap.c +++ b/pango/pangoft2-fontmap.c @@ -36,6 +36,8 @@ #include "pango-utils.h" #include "pangoft2-private.h" +#include "mini-xft/MiniXftFreetype.h" + #ifdef G_OS_WIN32 #define STRICT #include @@ -45,41 +47,46 @@ #define PANGO_FT2_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FT2_FONT_MAP, PangoFT2FontMap)) #define PANGO_FT2_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FT2_FONT_MAP)) -typedef struct _PangoFT2Family PangoFT2Family; typedef struct _PangoFT2FontMap PangoFT2FontMap; typedef struct _PangoFT2SizeInfo PangoFT2SizeInfo; +typedef struct _PangoFT2PatternSet PangoFT2PatternSet; /* Number of freed fonts */ #define MAX_FREED_FONTS 16 +struct _PangoFT2Family +{ + PangoFontFamily parent_instance; + + PangoFT2FontMap *fontmap; + char *family_name; + + PangoFT2Face **faces; + int n_faces; /* -1 == uninitialized */ +}; + + struct _PangoFT2FontMap { PangoFontMap parent_instance; FT_Library library; - PangoFT2FontCache *font_cache; - GQueue *freed_fonts; - - /* Maps Pango family names to PangoFT2FamilyEntry structs */ - GHashTable *families; - - /* Maps the family and style of a face to a PangoFT2OA struct */ - GHashTable *faces; + GHashTable *fontset_hash; /* Maps PangoFontDescription -> PangoXftFontSet */ + GHashTable *coverage_hash; /* Maps font file name -> PangoCoverage */ - int n_fonts; + GHashTable *fonts; /* Maps XftPattern -> PangoFT2Font */ + GQueue *freed_fonts; /* Fonts in fonts that has been freed */ - double resolution; /* (points / pixel) * PANGO_SCALE */ + /* List of all families availible */ + PangoFT2Family **families; + int n_families; /* -1 == uninitialized */ }; -struct _PangoFT2Family +struct _PangoFT2PatternSet { - PangoFontFamily parent_instance; - - char *family_name; - - /* List of PangoFT2FontEntry structs */ - GSList *font_entries; + int n_patterns; + MiniXftPattern **patterns; }; #define PANGO_FT2_TYPE_FAMILY (pango_ft2_family_get_type ()) @@ -94,32 +101,27 @@ 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 (PangoFontMapClass *class); +static void pango_ft2_font_map_init (PangoFT2FontMap *fontmap); +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 PangoFontset *pango_ft2_font_map_load_fontset (PangoFontMap *fontmap, + const PangoFontDescription *desc, + PangoLanguage *language); +static void pango_ft2_font_set_free (PangoFT2PatternSet *font_set); +static void pango_ft2_font_map_list_families (PangoFontMap *fontmap, + PangoFontFamily ***families, + int *n_families); +static void pango_ft2_font_map_cache_remove (PangoFontMap *fontmap, + PangoFT2Font *ft2font); +static void pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap); -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_families (PangoFontMap *fontmap, - PangoFontFamily ***families, - int *n_families); - -static void pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap); - -static void pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap); - -static void pango_ft2_insert_face (PangoFT2FontMap *fontmap, - FT_Face face, - const char *path, - int face_index); static PangoFontClass *parent_class; /* Parent class structure for PangoFT2FontMap */ static PangoFT2FontMap *pango_ft2_global_fontmap = NULL; -static char **pango_ft2_font_directories = NULL; static GType pango_ft2_font_map_get_type (void) @@ -149,131 +151,135 @@ pango_ft2_font_map_get_type (void) return object_type; } -static void -pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap) +static void +pango_ft2_font_set_free (PangoFT2PatternSet *font_set) { - ft2fontmap->families = g_hash_table_new (g_str_hash, g_str_equal); - ft2fontmap->faces = g_hash_table_new ((GHashFunc)pango_font_description_hash, - (GEqualFunc)pango_font_description_equal); - ft2fontmap->n_fonts = 0; + int i; + + for (i = 0; i < font_set->n_patterns; i++) + MiniXftPatternDestroy (font_set->patterns[i]); + + g_free (font_set); } -static void -pango_ft2_font_map_class_init (PangoFontMapClass *class) +static guint +pango_ft2_pattern_hash (MiniXftPattern *pattern) { - GObjectClass *object_class = G_OBJECT_CLASS (class); - char *font_path; - - parent_class = g_type_class_peek_parent (class); + char *str; + int i; + double d; + guint hash = 0; - object_class->finalize = pango_ft2_font_map_finalize; - class->load_font = pango_ft2_font_map_load_font; - class->list_families = pango_ft2_font_map_list_families; + MiniXftPatternGetString (pattern, XFT_FILE, 0, &str); + if (str) + hash = g_str_hash (str); - font_path = pango_config_key_get ("PangoFT2/FontPath"); + if (MiniXftPatternGetInteger (pattern, XFT_INDEX, 0, &i) == MiniXftResultMatch) + hash ^= i; - if (!font_path) - { - font_path = g_build_filename (pango_get_lib_subdirectory (), - "ft2fonts", - NULL); + if (MiniXftPatternGetDouble (pattern, XFT_PIXEL_SIZE, 0, &d) == MiniXftResultMatch) + hash ^= (guint) (d*1000.0); -#ifdef G_OS_WIN32 - { - char win_dir[100]; - char *tmp_str; - - GetWindowsDirectory (win_dir, sizeof (win_dir)); - tmp_str = g_build_filename (font_path, - win_dir, - "fonts", - NULL); - g_free (font_path); - font_path = tmp_str; - } -#endif - } - - pango_ft2_font_directories = pango_split_file_list (font_path); - g_free (font_path); + return hash; } static gboolean -pango_ft2_is_font_file (const char *name) -{ - int len; +pango_ft2_pattern_equal (MiniXftPattern *pattern1, + MiniXftPattern *pattern2) +{ + char *file1, *file2; + int index1, index2; + double size1, size2; + MiniXftResult res1, res2; + int int1, int2; + Bool bool1, bool2; + + MiniXftPatternGetString (pattern1, XFT_FILE, 0, &file1); + MiniXftPatternGetString (pattern2, XFT_FILE, 0, &file2); - len = strlen (name); - if (len > 4 && - (g_ascii_strncasecmp (&name[len-4], ".pfa", 4) == 0 || - g_ascii_strncasecmp (&name[len-4], ".pfb", 4) == 0 || - g_ascii_strncasecmp (&name[len-4], ".ttf", 4) == 0 || - g_ascii_strncasecmp (&name[len-4], ".ttc", 4) == 0)) - return TRUE; + g_assert (file1 != NULL && file2 != NULL); - return FALSE; + if (strcmp (file1, file2) != 0) + return FALSE; + + if (MiniXftPatternGetInteger (pattern1, XFT_INDEX, 0, &index1) != MiniXftResultMatch) + return FALSE; + + if (MiniXftPatternGetInteger (pattern2, XFT_INDEX, 0, &index2) != MiniXftResultMatch) + return FALSE; + + if (index1 != index2) + return FALSE; + + if (MiniXftPatternGetDouble (pattern1, XFT_PIXEL_SIZE, 0, &size1) != MiniXftResultMatch) + return FALSE; + + if (MiniXftPatternGetDouble (pattern2, XFT_PIXEL_SIZE, 0, &size2) != MiniXftResultMatch) + return FALSE; + + if (size1 != size2) + return FALSE; + + res1 = MiniXftPatternGetInteger (pattern1, XFT_RGBA, 0, &int1); + res2 = MiniXftPatternGetInteger (pattern2, XFT_RGBA, 0, &int2); + if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2)) + return FALSE; + + res1 = MiniXftPatternGetBool (pattern1, XFT_ANTIALIAS, 0, &bool1); + res2 = MiniXftPatternGetBool (pattern2, XFT_ANTIALIAS, 0, &bool2); + if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2)) + return FALSE; + + res1 = MiniXftPatternGetBool (pattern1, XFT_MINSPACE, 0, &bool1); + res2 = MiniXftPatternGetBool (pattern2, XFT_MINSPACE, 0, &bool2); + if (res1 != res2 || (res1 == MiniXftResultMatch && bool1 != bool2)) + return FALSE; + + res1 = MiniXftPatternGetInteger (pattern1, XFT_SPACING, 0, &int1); + res2 = MiniXftPatternGetInteger (pattern2, XFT_SPACING, 0, &int2); + if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2)) + return FALSE; + + res1 = MiniXftPatternGetInteger (pattern1, XFT_CHAR_WIDTH, 0, &int1); + res2 = MiniXftPatternGetInteger (pattern2, XFT_CHAR_WIDTH, 0, &int2); + if (res1 != res2 || (res1 == MiniXftResultMatch && int1 != int2)) + return FALSE; + + return TRUE; } -static gboolean -pango_ft2_scan_directory (const char *path, - PangoFT2FontMap *ft2fontmap) + +static void +pango_ft2_font_map_init (PangoFT2FontMap *ft2fontmap) { - DIR *dir; - struct dirent *entry; - char *fullname; - FT_Face face; - FT_Error error; - int i; - gboolean found_font = FALSE; - dir = opendir (path); - if (!dir) - /* Don't warn; it's OK to have nonexistent entries in the font path */ - return FALSE; + ft2fontmap->fonts = + g_hash_table_new ((GHashFunc)pango_ft2_pattern_hash, + (GEqualFunc)pango_ft2_pattern_equal); + ft2fontmap->fontset_hash = + g_hash_table_new_full ((GHashFunc)pango_font_description_hash, + (GEqualFunc)pango_font_description_equal, + (GDestroyNotify)pango_font_description_free, + (GDestroyNotify)pango_ft2_font_set_free); + + ft2fontmap->coverage_hash = + g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify)g_free, + (GDestroyNotify)pango_coverage_unref); + ft2fontmap->freed_fonts = g_queue_new (); +} - while ((entry = readdir (dir)) != NULL) - { - fullname = g_build_filename (path, entry->d_name, NULL); - if (pango_ft2_is_font_file (fullname)) - { - error = FT_New_Face (ft2fontmap->library, fullname, 0, &face); - if (error != FT_Err_Ok) - g_warning ("Error loading font from '%s': %s", - fullname, pango_ft2_ft_strerror (error)); - else - { - if (face->face_flags & FT_FACE_FLAG_SCALABLE) - { - pango_ft2_insert_face (ft2fontmap, face, fullname, 0); - found_font = TRUE; - } - - for (i = 1; i < face->num_faces; i++) - { - error = FT_Done_Face (face); - if (error != FT_Err_Ok) - g_warning ("Error from FT_Done_Face: %s", - pango_ft2_ft_strerror (error)); - error = FT_New_Face (ft2fontmap->library, fullname, i, &face); - if (error != FT_Err_Ok) - g_warning ("Error loading font %d from '%s': %s", - i, fullname, pango_ft2_ft_strerror (error)); - else if (face->face_flags & FT_FACE_FLAG_SCALABLE) - { - pango_ft2_insert_face (ft2fontmap, face, fullname, i); - found_font = TRUE; - } - } - error = FT_Done_Face (face); - if (error != FT_Err_Ok) - g_warning ("Error from FT_Done_Face: %s", - pango_ft2_ft_strerror (error)); - } - } - g_free (fullname); - } - closedir (dir); - return found_font; +static void +pango_ft2_font_map_class_init (PangoFontMapClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + + parent_class = g_type_class_peek_parent (class); + + object_class->finalize = pango_ft2_font_map_finalize; + class->load_font = pango_ft2_font_map_load_font; + class->load_fontset = pango_ft2_font_map_load_fontset; + class->list_families = pango_ft2_font_map_list_families; } /** @@ -288,9 +294,7 @@ pango_ft2_scan_directory (const char *path, PangoFontMap * pango_ft2_font_map_for_display (void) { - char **tmp_list; FT_Error error; - gboolean read_font; /* Make sure that the type system is initialized */ g_type_init (); @@ -304,27 +308,10 @@ pango_ft2_font_map_for_display (void) if (error != FT_Err_Ok) { g_warning ("Error from FT_Init_FreeType: %s", - pango_ft2_ft_strerror (error)); + _pango_ft2_ft_strerror (error)); return NULL; } - pango_ft2_global_fontmap->font_cache = pango_ft2_font_cache_new (pango_ft2_global_fontmap->library); - pango_ft2_global_fontmap->freed_fonts = g_queue_new (); - - tmp_list = pango_ft2_font_directories; - - read_font = FALSE; - while (*tmp_list) - { - read_font |= pango_ft2_scan_directory ((const char *) *tmp_list, pango_ft2_global_fontmap); - tmp_list++; - } - - if (!read_font) - g_warning ("No fonts found by pangoft2. Things will probably not work"); - - pango_ft2_font_map_read_aliases (pango_ft2_global_fontmap); - return PANGO_FONT_MAP (pango_ft2_global_fontmap); } @@ -336,34 +323,49 @@ pango_ft2_font_map_for_display (void) void pango_ft2_shutdown_display (void) { - pango_ft2_fontmap_cache_clear (pango_ft2_global_fontmap); + pango_ft2_font_map_cache_clear (pango_ft2_global_fontmap); g_object_unref (G_OBJECT (pango_ft2_global_fontmap)); pango_ft2_global_fontmap = NULL; } + static void pango_ft2_font_map_finalize (GObject *object) { PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (object); - g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); g_queue_free (ft2fontmap->freed_fonts); + g_hash_table_destroy (ft2fontmap->fontset_hash); + g_hash_table_destroy (ft2fontmap->coverage_hash); - pango_ft2_font_cache_free (ft2fontmap->font_cache); - FT_Done_FreeType (ft2fontmap->library); G_OBJECT_CLASS (parent_class)->finalize (object); } -static void -list_families_foreach (gpointer key, gpointer value, gpointer user_data) +/* Add a mapping from xfont->font_pattern to xfont */ +void +_pango_ft2_font_map_add (PangoFontMap *fontmap, + PangoFT2Font *ft2font) { - GSList **list = user_data; + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap; - *list = g_slist_prepend (*list, value); + g_hash_table_insert (ft2fontmap->fonts, + ft2font->font_pattern, + ft2font); +} + +/* Remove mapping from xfont->font_pattern to xfont */ +void +_pango_ft2_font_map_remove (PangoFontMap *fontmap, + PangoFT2Font *ft2font) +{ + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *) fontmap; + + g_hash_table_remove (ft2fontmap->fonts, + ft2font->font_pattern); } static void @@ -371,525 +373,232 @@ pango_ft2_font_map_list_families (PangoFontMap *fontmap, PangoFontFamily ***families, int *n_families) { - GSList *family_list = NULL; - GSList *tmp_list; PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; + MiniXftFontSet *fontset; + int i; - if (!n_families) - return; - - g_hash_table_foreach (ft2fontmap->families, list_families_foreach, &family_list); - - *n_families = g_slist_length (family_list); - - if (families) + if (ft2fontmap->n_families < 0) { - int i = 0; - - *families = g_new (PangoFontFamily *, *n_families); + fontset = MiniXftListFonts ((Display *)1, 0, + XFT_CORE, MiniXftTypeBool, False, + XFT_ENCODING, MiniXftTypeString, "iso10646-1", + NULL, + XFT_FAMILY, + NULL); + + ft2fontmap->n_families = fontset->nfont; + ft2fontmap->families = g_new (PangoFT2Family *, ft2fontmap->n_families); - tmp_list = family_list; - while (tmp_list) + for (i = 0; i < fontset->nfont; i++) { - (*families)[i] = tmp_list->data; - i++; - tmp_list = tmp_list->next; + char *s; + MiniXftResult res; + + res = MiniXftPatternGetString (fontset->fonts[i], XFT_FAMILY, 0, &s); + g_assert (res == MiniXftResultMatch); + + ft2fontmap->families[i] = g_object_new (PANGO_FT2_TYPE_FAMILY, NULL); + ft2fontmap->families[i]->family_name = g_strdup (s); + ft2fontmap->families[i]->fontmap = ft2fontmap; } + + MiniXftFontSetDestroy (fontset); } - g_slist_free (family_list); + if (n_families) + *n_families = ft2fontmap->n_families; + + if (families) + *families = g_memdup (ft2fontmap->families, ft2fontmap->n_families * sizeof (PangoFontFamily *)); } -static PangoFT2Family * -pango_ft2_get_family (PangoFT2FontMap *ft2fontmap, - const char *family_name) +static int +pango_ft2_convert_weight (PangoWeight pango_weight) { - PangoFT2Family *ft2family = g_hash_table_lookup (ft2fontmap->families, family_name); - if (!ft2family) - { - 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, ft2family->family_name, ft2family); - } - - return ft2family; + int weight; + + if (pango_weight < (PANGO_WEIGHT_NORMAL + PANGO_WEIGHT_LIGHT) / 2) + weight = XFT_WEIGHT_LIGHT; + else if (pango_weight < (PANGO_WEIGHT_NORMAL + 600) / 2) + weight = XFT_WEIGHT_MEDIUM; + else if (pango_weight < (600 + PANGO_WEIGHT_BOLD) / 2) + weight = XFT_WEIGHT_DEMIBOLD; + else if (pango_weight < (PANGO_WEIGHT_BOLD + PANGO_WEIGHT_ULTRABOLD) / 2) + weight = XFT_WEIGHT_BOLD; + else + weight = XFT_WEIGHT_BLACK; + + return weight; } -static PangoFont * -pango_ft2_font_map_load_font (PangoFontMap *fontmap, - const PangoFontDescription *description) +static int +pango_ft2_convert_slant (PangoStyle pango_style) { - PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; - PangoFT2Family *family_entry; - PangoFont *result = NULL; - GSList *tmp_list; - gchar *name; - - g_return_val_if_fail (description != NULL, NULL); + int slant; - name = g_ascii_strdown (pango_font_description_get_family (description), -1); - - family_entry = g_hash_table_lookup (ft2fontmap->families, name); - g_free (name); + if (pango_style == PANGO_STYLE_ITALIC) + slant = XFT_SLANT_ITALIC; + else if (pango_style == PANGO_STYLE_OBLIQUE) + slant = XFT_SLANT_OBLIQUE; + else + slant = XFT_SLANT_ROMAN; - if (family_entry) - { - PangoFT2Face *best_match = NULL; - - tmp_list = family_entry->font_entries; - while (tmp_list) - { - PangoFT2Face *face = tmp_list->data; - - if (pango_font_description_better_match (description, - best_match ? best_match->description : NULL, - face->description)) - best_match = face; - - tmp_list = tmp_list->next; - } - - if (best_match) - { - 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 == size) - { - result = (PangoFont *)ft2font; - - g_object_ref (G_OBJECT (result)); - if (ft2font->in_cache) - pango_ft2_fontmap_cache_remove (fontmap, ft2font); - break; - } - tmp_list = tmp_list->next; - } - - if (!result) - { - PangoFT2Font *ft2font = - (PangoFT2Font *) pango_ft2_load_font (fontmap, - best_match->open_args, - best_match->face_indices, - best_match->n_fonts, - size); - - ft2font->fontmap = fontmap; - ft2font->entry = best_match; - best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, ft2font); - - result = (PangoFont *)ft2font; - } - } - } - - return result; + return slant; } -static gboolean -pango_ft2_font_map_read_alias_file (PangoFT2FontMap *ft2fontmap, - const char *filename) -{ - FILE *infile; - int lineno = 0; - int nfaces; - int i; - PangoFT2Face *face = NULL; - gchar **faces; - gboolean ret_val = FALSE; - - infile = fopen (filename, "r"); - if (infile) - { - GString *line_buf = g_string_new (NULL); - GString *tmp_buf = g_string_new (NULL); - - while (pango_read_line (infile, line_buf)) - { - PangoFT2Family *family_entry; - PangoStyle style; - PangoVariant variant; - PangoWeight weight; - PangoStretch stretch; - - const char *p = line_buf->str; - - lineno++; - - if (!pango_skip_space (&p)) - continue; - - if (!pango_scan_string (&p, tmp_buf)) - goto error; - - face = g_object_new (PANGO_FT2_TYPE_FACE, NULL); - face->n_fonts = 0; - face->open_args = NULL; - face->face_indices = NULL; - - 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, &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, &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, &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, &stretch, TRUE)) - goto error; - pango_font_description_set_stretch (face->description, stretch); - - if (!pango_scan_string (&p, tmp_buf)) - goto error; - - /* Remove excess whitespace and check for complete fields */ - faces = g_strsplit (tmp_buf->str, ",", -1); - nfaces = 0; - for (i = 0; faces[i]; i++) - { - char *trimmed = pango_trim_string (faces[i]); - g_free (faces[i]); - faces[i] = trimmed; - 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 = pango_font_description_copy_static (face->description); - PangoFT2OA *oa; - - 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 - { - 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 (ft2fontmap, pango_font_description_get_family (face->description)); - family_entry->font_entries = g_slist_prepend (family_entry->font_entries, face); - ft2fontmap->n_fonts++; - - /* 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)) - g_warning ("Error reading file '%s': %s", filename, g_strerror(errno)); - - ret_val = TRUE; - goto out; - - error: - if (face) - { - 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); - - out: - g_string_free (tmp_buf, TRUE); - g_string_free (line_buf, TRUE); +static MiniXftPattern * +pango_ft2_make_pattern (const PangoFontDescription *description) +{ + MiniXftPattern *pattern; + PangoStyle pango_style; + int slant; + int weight; + + pango_style = pango_font_description_get_style (description); - fclose (infile); - } + slant = pango_ft2_convert_slant (pango_style); + weight = pango_ft2_convert_weight (pango_font_description_get_weight (description)); + + /* To fool Xft into not munging glyph indices, we open it as glyphs-fontspecific + * then set the encoding ourself + */ + pattern = MiniXftPatternBuild (0, + XFT_ENCODING, MiniXftTypeString, "glyphs-fontspecific", + XFT_CORE, MiniXftTypeBool, False, + XFT_FAMILY, MiniXftTypeString, pango_font_description_get_family (description), + XFT_WEIGHT, MiniXftTypeInteger, weight, + XFT_SLANT, MiniXftTypeInteger, slant, + XFT_SIZE, MiniXftTypeDouble, (double)pango_font_description_get_size (description)/PANGO_SCALE, + NULL); - return ret_val; + return pattern; } -static void -pango_ft2_font_map_read_aliases (PangoFT2FontMap *ft2fontmap) +static PangoFont * +pango_ft2_font_map_new_font (PangoFontMap *fontmap, + MiniXftPattern *match) { - char **files; - char *files_str = pango_config_key_get ("PangoFT2/AliasFiles"); - int n; - gboolean read_aliasfile; - - if (!files_str) + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; + PangoFT2Font *font; + + /* Look up cache */ + font = g_hash_table_lookup (ft2fontmap->fonts, match); + + if (font) { - const char *home = g_get_home_dir (); - char *file1 = NULL; - char *file2; - - if (home && *home) - file1 = g_build_filename (home, ".pangoft2_aliases", NULL); + /* Revive fonts from cache */ + if (font->in_cache) + pango_ft2_font_map_cache_remove (fontmap, font); - file2 = g_build_filename (pango_get_sysconf_subdirectory (), - "pangoft2.aliases", - NULL); - - files_str = g_build_path (G_SEARCHPATH_SEPARATOR_S, - file1 ? file1 : file2, - file1 ? file2 : NULL, - NULL); - - g_free (file1); - g_free (file2); + return (PangoFont *)g_object_ref (G_OBJECT(font)); } - - files = pango_split_file_list (files_str); - - n = 0; - while (files[n]) - n++; - - - read_aliasfile = FALSE; - while (n-- > 0) - read_aliasfile |= pango_ft2_font_map_read_alias_file (ft2fontmap, files[n]); - - if (!read_aliasfile) - g_warning ("Didn't read any pango ft2 fontalias file. Things will probably not work."); - - g_strfreev (files); - g_free (files_str); + return (PangoFont *)_pango_ft2_font_new (fontmap, MiniXftPatternDuplicate (match)); } -#if DEBUGGING -static void -pango_print_desc (PangoFontDescription *desc) +static PangoFont * +pango_ft2_font_map_load_font (PangoFontMap *fontmap, + const PangoFontDescription *description) { - 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); + MiniXftPattern *pattern, *match; + MiniXftResult res; + + pattern = pango_ft2_make_pattern (description); + + match = MiniXftFontMatch ((Display *)1, 0, pattern, &res); + + MiniXftPatternDestroy (pattern); - g_print ("%s%s%s%s%s", - pango_font_description_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"))))), - (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" : " ???")))))))))); -} + if (match) + return pango_ft2_font_map_new_font (fontmap, match); -static void -pango_ft2_print_oa (PangoFT2OA *oa) -{ - g_print ("%s:%ld", oa->open_args->pathname, oa->face_index); + return NULL; } -#endif - -static void -pango_ft2_insert_face (PangoFT2FontMap *ft2fontmap, - FT_Face face, - const char *path, - int face_index) +static PangoFontset * +pango_ft2_font_map_load_fontset (PangoFontMap *fontmap, + const PangoFontDescription *desc, + PangoLanguage *language) { - PangoFontDescription *description; - char *family_name; - PangoStyle style; - PangoVariant variant; - PangoWeight weight; - PangoStretch stretch; - GSList *tmp_list; - PangoFT2Family *family_entry; - PangoFT2Face *face_entry; - PangoFT2OA *oa; - FT_Open_Args *open_args; - - family_name = g_ascii_strdown (face->family_name, -1); - - if (face->style_flags & FT_STYLE_FLAG_ITALIC) - style = PANGO_STYLE_ITALIC; - else - style = PANGO_STYLE_NORMAL; - - variant = PANGO_VARIANT_NORMAL; - - if (face->style_flags & FT_STYLE_FLAG_BOLD) - weight = PANGO_WEIGHT_BOLD; - else - weight = PANGO_WEIGHT_NORMAL; + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; + MiniXftPattern *pattern, *pattern_copy; + MiniXftPattern *match; + int i; + char *family, *family_res; + MiniXftResult res; + GPtrArray *array; + int id; + PangoFT2PatternSet *patterns; + PangoFontsetSimple *simple; - stretch = PANGO_STRETCH_NORMAL; + patterns = g_hash_table_lookup (ft2fontmap->fontset_hash, desc); - if (face->style_name) + if (patterns == NULL) { - gchar **styles = g_strsplit (face->style_name, " ", 0); - gint i = 0; + pattern = pango_ft2_make_pattern (desc); - while (styles[i]) - { - (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); - } + MiniXftConfigSubstitute (pattern); + MiniXftDefaultSubstitute ((Display *)1, 0, pattern); -#if 0 - PING (("")); - pango_print_desc (description); -#endif + pattern_copy = MiniXftPatternDuplicate (pattern); - family_entry = pango_ft2_get_family (ft2fontmap, family_name); - g_free (family_name); + array = g_ptr_array_new (); + patterns = g_new (PangoFT2PatternSet, 1); - tmp_list = family_entry->font_entries; - while (tmp_list) - { - face_entry = tmp_list->data; + MiniXftInit (0); + MiniXftInitFtLibrary (); + + match = NULL; + id = 0; + while (MiniXftPatternGetString (pattern, XFT_FAMILY, id++, &family) == MiniXftResultMatch) + { + MiniXftPatternDel (pattern_copy, XFT_FAMILY); + MiniXftPatternAddString (pattern_copy, XFT_FAMILY, family); - 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) + match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern_copy, &res); + + if (match && + MiniXftPatternGetString (match, XFT_FAMILY, 0, &family_res) == MiniXftResultMatch && + g_ascii_strcasecmp (family, family_res) == 0) + { + patterns->patterns[patterns->n_patterns++] = match; + match = NULL; + } + if (match) + MiniXftPatternDestroy (match); + } + + if (array->len == 0) { -#if 0 - PING ((" family and description matched (!)")); -#endif - return; + match = MiniXftFontSetMatch (&_MiniXftFontSet, 1, pattern, &res); + patterns->patterns[patterns->n_patterns++] = match; } - tmp_list = tmp_list->next; - } + MiniXftPatternDestroy (pattern); + MiniXftPatternDestroy (pattern_copy); - 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) - { - oa = g_new (PangoFT2OA, 1); - open_args = g_new (FT_Open_Args, 1); - open_args->flags = ft_open_pathname; - open_args->pathname = g_strdup (path); - open_args->driver = NULL; - open_args->num_params = 0; - oa->open_args = open_args; - oa->face_index = face_index; -#if 0 - PING (("adding mapping: ")); - pango_ft2_print_oa (oa); -#endif - g_hash_table_insert (ft2fontmap->faces, description, oa); + patterns->n_patterns = array->len; + patterns->patterns = (MiniXftPattern **)g_ptr_array_free (array, FALSE); + + g_hash_table_insert (ft2fontmap->fontset_hash, + pango_font_description_copy (desc), + patterns); } -#if 0 - g_print ("\n"); -#endif - 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++; -} - -static void -free_coverages_foreach (gpointer key, - gpointer value, - gpointer data) -{ - pango_coverage_unref (value); -} - -/** - * pango_ft2_font_map_get_font_cache: - * @font_map: a #PangoFT2FontMap. - * - * Obtains the font cache associated with the given font map. - * - * Returns: the #PangoFT2FontCache of @font_map. - **/ -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); + simple = pango_fontset_simple_new (language); - return PANGO_FT2_FONT_MAP (font_map)->font_cache; + for (i = 0; i < patterns->n_patterns; i++) + pango_fontset_simple_append (simple, + pango_ft2_font_map_new_font (fontmap, patterns->patterns[i])); + + return PANGO_FONTSET (simple); } void -pango_ft2_fontmap_cache_add (PangoFontMap *fontmap, - PangoFT2Font *ft2font) +_pango_ft2_font_map_cache_add (PangoFontMap *fontmap, + PangoFT2Font *ft2font) { PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); @@ -904,9 +613,9 @@ pango_ft2_fontmap_cache_add (PangoFontMap *fontmap, ft2font->in_cache = TRUE; } -void -pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap, - PangoFT2Font *ft2font) +static void +pango_ft2_font_map_cache_remove (PangoFontMap *fontmap, + PangoFT2Font *ft2font) { PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); @@ -926,7 +635,7 @@ pango_ft2_fontmap_cache_remove (PangoFontMap *fontmap, } static void -pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap) +pango_ft2_font_map_cache_clear (PangoFT2FontMap *ft2fontmap) { g_list_foreach (ft2fontmap->freed_fonts->head, (GFunc)g_object_unref, NULL); g_list_free (ft2fontmap->freed_fonts->head); @@ -935,98 +644,95 @@ pango_ft2_fontmap_cache_clear (PangoFT2FontMap *ft2fontmap) ft2fontmap->freed_fonts->length = 0; } -static void -pango_ft2_face_dump (int indent, - PangoFT2Face *face) +/* + * PangoFT2Face + */ + +PangoFontDescription * +_pango_ft2_font_desc_from_pattern (MiniXftPattern *pattern) { + PangoFontDescription *desc; + PangoStyle style; + PangoWeight weight; + + char *s; 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); -} + desc = pango_font_description_new (); -static void -pango_ft2_family_entry_dump (int indent, - PangoFT2Family *entry) -{ - GSList *tmp_list = entry->font_entries; + g_assert (MiniXftPatternGetString (pattern, XFT_FAMILY, 0, &s) == MiniXftResultMatch); + + pango_font_description_set_family (desc, s); - printf ("%*sPangoFT2Family@%p:\n" - "%*s family_name: %s\n" - "%*s font_entries:\n", - indent, "", entry, - indent, "", entry->family_name, - indent, ""); - - while (tmp_list) + if (MiniXftPatternGetInteger (pattern, XFT_SLANT, 0, &i) == MiniXftResultMatch) { - PangoFT2Face *face = tmp_list->data; - - pango_ft2_face_dump (indent + 2, face); - tmp_list = tmp_list->next; + if (i == XFT_SLANT_ROMAN) + style = PANGO_STYLE_NORMAL; + else if (i == XFT_SLANT_OBLIQUE) + style = PANGO_STYLE_OBLIQUE; + else + style = PANGO_STYLE_ITALIC; } -} - -static void -dump_family (gpointer key, - gpointer value, - gpointer user_data) -{ - PangoFT2Family *entry = value; - int indent = (int) user_data; + else + style = PANGO_STYLE_NORMAL; - pango_ft2_family_entry_dump (indent, entry); -} + pango_font_description_set_style (desc, style); + + if (MiniXftPatternGetInteger (pattern, XFT_WEIGHT, 0, &i) == MiniXftResultMatch) + { + 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_ft2_fontmap_dump: - * @indent: the indent to use. - * @fontmap: a #PangoFT2FontMap. - * - * Writes a description of the given font map to stdout. - **/ -void -pango_ft2_fontmap_dump (int indent, - PangoFontMap *fontmap) -{ - PangoFT2FontMap *ft2fontmap = PANGO_FT2_FONT_MAP (fontmap); + 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); - printf ("%*sPangoFT2FontMap@%p:\n", - indent, "", ft2fontmap); - g_hash_table_foreach (ft2fontmap->families, dump_family, (gpointer) (indent + 2)); + return desc; } -/* - * PangoFT2Face - */ static PangoFontDescription * pango_ft2_face_describe (PangoFontFace *face) { - PangoFT2Face *ft2face = PANGO_FT2_FACE (face); + PangoFT2Face *ft2face = (PangoFT2Face *) face; + PangoFT2Family *ft2family = ft2face->family; + PangoFontDescription *desc = NULL; + MiniXftResult res; + MiniXftPattern *match_pattern; + MiniXftPattern *result_pattern; + + match_pattern = MiniXftPatternBuild (NULL, + XFT_ENCODING, MiniXftTypeString, "iso10646-1", + XFT_FAMILY, MiniXftTypeString, ft2family->family_name, + XFT_CORE, MiniXftTypeBool, False, + XFT_STYLE, MiniXftTypeString, ft2face->style, + NULL); + g_assert (match_pattern); + + result_pattern = MiniXftFontMatch ((Display *)1, 0, match_pattern, &res); + if (result_pattern) + { + desc = _pango_ft2_font_desc_from_pattern (result_pattern); + MiniXftPatternDestroy (result_pattern); + } - return pango_font_description_copy (ft2face->description); + MiniXftPatternDestroy (match_pattern); + + return desc; } static const char * @@ -1034,18 +740,7 @@ 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; + return ft2face->style; } static void @@ -1083,112 +778,32 @@ pango_ft2_face_get_type (void) return object_type; } -PangoCoverage * -pango_ft2_face_get_coverage (PangoFT2Face *face, - PangoFont *font, - PangoLanguage *language) +void +_pango_ft2_font_map_set_coverage (PangoFontMap *fontmap, + const char *name, + PangoCoverage *coverage) { - guint32 ch; - PangoMap *shape_map; - PangoCoverage *coverage; - PangoCoverage *result; - PangoCoverageLevel font_level; - PangoMapEntry *map_entry; - GHashTable *coverage_hash; - PangoFontDescription *description; - FILE *cache_file; - char *file_name; - char *cache_file_name; - char *font_as_filename; - guchar *buf; - size_t buflen; - - if (face) - if (face->coverage) - { - pango_coverage_ref (face->coverage); - return face->coverage; - } - - description = pango_font_describe (font); - font_as_filename = pango_font_description_to_filename (description); - file_name = g_strconcat (font_as_filename, ".", - language ? pango_language_to_string (language) : "", - NULL); - g_free (font_as_filename); - cache_file_name = g_build_filename (pango_get_sysconf_subdirectory (), - "cache.ft2", file_name, NULL); - g_free (file_name); - pango_font_description_free (description); - - PING (("trying to load %s", cache_file_name)); - result = NULL; - if (g_file_get_contents (cache_file_name, (char **)&buf, &buflen, NULL)) - { - result = pango_coverage_from_bytes (buf, buflen); - g_free (buf); - } - - if (!result) - { - result = pango_coverage_new (); - - coverage_hash = g_hash_table_new (g_str_hash, g_str_equal); - - shape_map = pango_ft2_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); - - cache_file = fopen (cache_file_name, "wb"); - if (cache_file) - { - pango_coverage_to_bytes (result, &buf, &buflen); - PING (("saving %d bytes to %s", buflen, cache_file_name)); - fwrite (buf, buflen, 1, cache_file); - fclose (cache_file); - g_free (buf); - } - } + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; - if (face) - { - face->coverage = result; - pango_coverage_ref (result); - } + g_hash_table_insert (ft2fontmap->coverage_hash, g_strdup (name), + pango_coverage_ref (coverage)); +} - g_free (cache_file_name); +PangoCoverage * +_pango_ft2_font_map_get_coverage (PangoFontMap *fontmap, + const char *name) +{ + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; - return result; + return g_hash_table_lookup (ft2fontmap->coverage_hash, name); } -void -pango_ft2_face_remove (PangoFT2Face *face, - PangoFont *font) +FT_Library +_pango_ft2_font_map_get_library (PangoFontMap *fontmap) { - face->cached_fonts = g_slist_remove (face->cached_fonts, font); + PangoFT2FontMap *ft2fontmap = (PangoFT2FontMap *)fontmap; + + return ft2fontmap->library; } /* @@ -1197,26 +812,48 @@ pango_ft2_face_remove (PangoFT2Face *face, static void pango_ft2_family_list_faces (PangoFontFamily *family, - PangoFontFace ***faces, - int *n_faces) + PangoFontFace ***faces, + int *n_faces) { PangoFT2Family *ft2family = PANGO_FT2_FAMILY (family); - *n_faces = g_slist_length (ft2family->font_entries); - if (faces) + if (ft2family->n_faces < 0) { - GSList *tmp_list; - int i = 0; + MiniXftFontSet *fontset; + int i; + + fontset = MiniXftListFonts ((Display *)1, 0, + XFT_ENCODING, MiniXftTypeString, "iso10646-1", + XFT_FAMILY, MiniXftTypeString, ft2family->family_name, + XFT_CORE, MiniXftTypeBool, False, + NULL, + XFT_STYLE, + NULL); - *faces = g_new (PangoFontFace *, *n_faces); + ft2family->n_faces = fontset->nfont; + ft2family->faces = g_new (PangoFT2Face *, ft2family->n_faces); - tmp_list = ft2family->font_entries; - while (tmp_list) + for (i = 0; i < fontset->nfont; i++) { - (*faces)[i++] = tmp_list->data; - tmp_list = tmp_list->next; + char *s; + MiniXftResult res; + + res = MiniXftPatternGetString (fontset->fonts[i], XFT_STYLE, 0, &s); + g_assert (res == MiniXftResultMatch); + + ft2family->faces[i] = g_object_new (PANGO_FT2_TYPE_FACE, NULL); + ft2family->faces[i]->style = g_strdup (s); + ft2family->faces[i]->family = ft2family; } + + MiniXftFontSetDestroy (fontset); } + + if (n_faces) + *n_faces = ft2family->n_faces; + + if (faces) + *faces = g_memdup (ft2family->faces, ft2family->n_faces * sizeof (PangoFontFace *)); } const char * -- cgit v1.2.1