summaryrefslogtreecommitdiff
path: root/pango/pangoft2-fontmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'pango/pangoft2-fontmap.c')
-rw-r--r--pango/pangoft2-fontmap.c1313
1 files changed, 475 insertions, 838 deletions
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 <windows.h>
@@ -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 *