summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-02-11 06:14:28 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-02-11 06:14:28 +0000
commitb1c021842d26d5674a51f802f29e2a8496767c55 (patch)
tree58e8cf4cbaa464eaf728fc38e7aa1bbfb1cb24c3
parent11884d20295c2aea6dfeb8a915dd02b48ec60d9c (diff)
downloadpango-b1c021842d26d5674a51f802f29e2a8496767c55.tar.gz
Add style selector, rewrite family selector to use list_families().
Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com> * examples/viewer.c: Add style selector, rewrite family selector to use list_families(). * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c libpango/fonts.c: Add calls to list families, modify list_fonts() call to take an optional "family" parameter for the purpose of listing the fonts within a family.
-rw-r--r--ChangeLog10
-rw-r--r--ChangeLog.pre-1-010
-rw-r--r--ChangeLog.pre-1-1010
-rw-r--r--ChangeLog.pre-1-210
-rw-r--r--ChangeLog.pre-1-410
-rw-r--r--ChangeLog.pre-1-610
-rw-r--r--ChangeLog.pre-1-810
-rw-r--r--TODO3
-rw-r--r--docs/tmpl/coverage-maps.sgml10
-rw-r--r--examples/viewer.c259
-rw-r--r--pango/fonts.c46
-rw-r--r--pango/pango-context.c115
-rw-r--r--pango/pango-context.h4
-rw-r--r--pango/pango-font.h44
-rw-r--r--pango/pangox.c106
15 files changed, 594 insertions, 63 deletions
diff --git a/ChangeLog b/ChangeLog
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-0 b/ChangeLog.pre-1-0
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-0
+++ b/ChangeLog.pre-1-0
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-2 b/ChangeLog.pre-1-2
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-2
+++ b/ChangeLog.pre-1-2
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-4 b/ChangeLog.pre-1-4
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-4
+++ b/ChangeLog.pre-1-4
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-6 b/ChangeLog.pre-1-6
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-6
+++ b/ChangeLog.pre-1-6
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/ChangeLog.pre-1-8 b/ChangeLog.pre-1-8
index 6dc6b5c1..caf182ba 100644
--- a/ChangeLog.pre-1-8
+++ b/ChangeLog.pre-1-8
@@ -1,3 +1,13 @@
+Thu Feb 10 19:57:27 2000 Owen Taylor <otaylor@redhat.com>
+
+ * examples/viewer.c: Add style selector, rewrite family
+ selector to use list_families().
+
+ * libpango/pango-context.[ch] libpango/pango-font.h libpango/pangox.c
+ libpango/fonts.c: Add calls to list families, modify list_fonts()
+ call to take an optional "family" parameter for the purpose of
+ listing the fonts within a family.
+
Wed Feb 9 14:04:35 2000 Owen Taylor <otaylor@redhat.com>
* TODO: updates.
diff --git a/TODO b/TODO
index 0bf999ab..984a7386 100644
--- a/TODO
+++ b/TODO
@@ -63,6 +63,9 @@ Documentation
General
=======
+* pango_context_list_fonts does not properly suppress duplicates
+ when multiple font maps are involved
+
* Report errors from functions, these errors include such things.
- Invalid string
diff --git a/docs/tmpl/coverage-maps.sgml b/docs/tmpl/coverage-maps.sgml
index 2347100a..daaa6b01 100644
--- a/docs/tmpl/coverage-maps.sgml
+++ b/docs/tmpl/coverage-maps.sgml
@@ -20,7 +20,7 @@ to represent that information.
<!-- ##### ENUM PangoCoverageLevel ##### -->
<para>
Used to indicate how well a font can represent a particular ISO 10646
-character point.
+character point for a particular scrpt.
</para>
@PANGO_COVERAGE_NONE: The character is not representable with the font.
@@ -29,10 +29,10 @@ character point.
For instance, a Hangul character represented as a
a sequence of Jamos, or a Latin transliteration of
a Cyrillic word.
-@PANGO_COVERAGE_APPROXIMATE: The character is represented as the correct graphical
- form but not in the ideal fashion.
-@PANGO_COVERAGE_EXACT: The character is represented as the correct graphical form,
- in an attractive manner.
+@PANGO_COVERAGE_APPROXIMATE: The character is represented as basically the correct
+ graphical form, but with a stylistic variant inappropriate for
+ the current script.
+@PANGO_COVERAGE_EXACT: The character is represented as the correct graphical form.
<!-- ##### STRUCT PangoCoverage ##### -->
<para>
diff --git a/examples/viewer.c b/examples/viewer.c
index 22d483ce..2946dd70 100644
--- a/examples/viewer.c
+++ b/examples/viewer.c
@@ -66,11 +66,16 @@ static PangoFont *font = NULL;
static Paragraph *highlight_para;
static int highlight_offset;
+GtkWidget *styles_combo;
+
static GtkWidget *message_label;
GtkWidget *layout;
PangoContext *context;
+static void fill_styles_combo (GtkWidget *combo);
+static void font_description_from_string (PangoFontDescription *desc, const char *name);
+
/* Read an entire file into a string
*/
static char *
@@ -818,6 +823,17 @@ void
set_family (GtkWidget *entry, gpointer data)
{
font_description.family_name = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+ fill_styles_combo (styles_combo);
+}
+
+void
+set_style (GtkWidget *entry, gpointer data)
+{
+ char *str = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
+
+ font_description_from_string (&font_description, str);
+ g_free (str);
+
reload_font ();
}
@@ -828,32 +844,233 @@ font_size_changed (GtkAdjustment *adj)
reload_font();
}
-GtkWidget *
-make_families_menu ()
+typedef struct
+{
+ int value;
+ const char *str;
+} FieldMap;
+
+FieldMap style_map[] = {
+ { PANGO_STYLE_NORMAL, NULL },
+ { PANGO_STYLE_OBLIQUE, "Oblique" },
+ { PANGO_STYLE_ITALIC, "Italic" }
+};
+
+FieldMap variant_map[] = {
+ { PANGO_VARIANT_NORMAL, NULL },
+ { PANGO_VARIANT_SMALL_CAPS, "Small-Caps" }
+};
+
+FieldMap weight_map[] = {
+ { 300, "Light" },
+ { PANGO_WEIGHT_NORMAL, NULL },
+ { 500, "Medium" },
+ { 600, "Semi-Bold" },
+ { PANGO_WEIGHT_BOLD, "Bold" }
+};
+
+FieldMap stretch_map[] = {
+ { PANGO_STRETCH_ULTRA_CONDENSED, "Ultra-Condensed" },
+ { PANGO_STRETCH_EXTRA_CONDENSED, "Extra-Condensed" },
+ { PANGO_STRETCH_CONDENSED, "Condensed" },
+ { PANGO_STRETCH_SEMI_CONDENSED, "Semi-Condensed" },
+ { PANGO_STRETCH_NORMAL, NULL },
+ { PANGO_STRETCH_SEMI_EXPANDED, "Semi-Expanded" },
+ { PANGO_STRETCH_EXPANDED, "Expanded" },
+ { PANGO_STRETCH_EXTRA_EXPANDED, "Extra-Expanded" },
+ { PANGO_STRETCH_ULTRA_EXPANDED, "Ultra-Expanded" }
+};
+
+static void
+append_field (GString *str, FieldMap *map, int n_elements, int val)
{
- GtkWidget *combo;
- GHashTable *families_hash = g_hash_table_new (g_str_hash, g_str_equal);
- GList *families = NULL;
int i;
+ for (i=0; i<n_elements; i++)
+ {
+ if (map[i].value == val)
+ {
+ if (map[i].str)
+ {
+ if (str->len != 0)
+ g_string_append_c (str, ' ');
+ g_string_append (str, map[i].str);
+ }
+ return;
+ }
+ }
- PangoFontDescription **descs;
- int n_descs;
+ if (str->len != 0)
+ g_string_append_c (str, ' ');
+ g_string_sprintfa (str, "%d", val);
+}
+
+static char *
+font_description_to_string (PangoFontDescription *desc)
+{
+ GString *result = g_string_new (NULL);
+ gchar *str;
- pango_context_list_fonts (context, &descs, &n_descs);
+ append_field (result, style_map, G_N_ELEMENTS (style_map), desc->style);
+ append_field (result, variant_map, G_N_ELEMENTS (variant_map), desc->variant);
+ append_field (result, weight_map, G_N_ELEMENTS (weight_map), desc->weight);
+ append_field (result, stretch_map, G_N_ELEMENTS (stretch_map), desc->stretch);
- for (i=0; i<n_descs; i++)
+ if (result->len == 0)
+ g_string_append (result, "Normal");
+
+ str = result->str;
+ g_string_free (result, FALSE);
+ return str;
+}
+
+static gboolean
+find_field (FieldMap *map, int n_elements, gchar *str, int *val)
+{
+ int i;
+
+ for (i=0; i<n_elements; i++)
{
- if (!g_hash_table_lookup (families_hash, descs[i]->family_name))
+ if (map[i].str && strcasecmp (map[i].str, str) == 0)
{
- g_hash_table_insert (families_hash, descs[i]->family_name, descs[i]);
- families = g_list_prepend (families, descs[i]->family_name);
+ *val = map[i].value;
+ return TRUE;
}
}
- families = g_list_sort (families, (GCompareFunc)strcmp);
+ return FALSE;
+}
+
+static void
+font_description_from_string (PangoFontDescription *desc, const char *name)
+{
+ gchar **words;
+ int i;
+
+ desc->style = PANGO_STYLE_NORMAL;
+ desc->variant = PANGO_VARIANT_NORMAL;
+ desc->weight = PANGO_WEIGHT_NORMAL;
+ desc->stretch = PANGO_STRETCH_NORMAL;
+
+ words = g_strsplit (name, " ", -1);
+ for (i=0; words[i]; i++)
+ {
+ if (!(find_field (style_map, G_N_ELEMENTS (style_map), words[i], (int *)&desc->style) ||
+ find_field (variant_map, G_N_ELEMENTS (variant_map), words[i], (int *)&desc->variant) ||
+ find_field (weight_map, G_N_ELEMENTS (weight_map), words[i], (int *)&desc->weight) ||
+ find_field (stretch_map, G_N_ELEMENTS (stretch_map), words[i], (int *)&desc->stretch)))
+ g_warning ("Unknown style modifier '%s'\n", words[i]);
+ }
+
+ g_strfreev (words);
+}
+
+static int
+compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
+{
+ int val = strcmp (a->family_name, b->family_name);
+ if (val != 0)
+ return val;
+
+ if (a->style != b->style)
+ return a->style - b->style;
+
+ if (a->variant != b->variant)
+ return a->variant - b->variant;
+
+ if (a->weight != b->weight)
+ return a->weight - b->weight;
+
+ if (a->stretch != b->stretch)
+ return a->stretch - b->stretch;
+
+ return 0;
+}
+
+static int
+font_description_sort_func (const PangoFontDescription **a, const PangoFontDescription **b)
+{
+ return compare_font_descriptions (*a, *b);
+}
+
+typedef struct
+{
+ PangoFontDescription **descs;
+ int n_descs;
+} FontDescInfo;
+
+static void
+free_info (FontDescInfo *info)
+{
+ pango_font_descriptions_free (info->descs, info->n_descs);
+}
+
+static void
+fill_styles_combo (GtkWidget *combo)
+{
+ int i;
+ GList *style_list = NULL;
+
+ FontDescInfo *info = g_new (FontDescInfo, 1);
+ pango_context_list_fonts (context, font_description.family_name, &info->descs, &info->n_descs);
+ gtk_object_set_data_full (GTK_OBJECT (combo), "descs", info, (GtkDestroyNotify)free_info);
+
+ qsort (info->descs, info->n_descs, sizeof(PangoFontDescription *), font_description_sort_func);
+
+ for (i=0; i<info->n_descs; i++)
+ {
+ char *str = font_description_to_string (info->descs[i]);
+ style_list = g_list_prepend (style_list, str);
+ }
+
+ style_list = g_list_reverse (style_list);
+
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), style_list);
+ g_list_foreach (style_list, (GFunc)g_free, NULL);
+}
+
+static GtkWidget *
+make_styles_combo ()
+{
+ GtkWidget *combo;
+
+ combo = gtk_combo_new ();
+ gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
+ gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE);
+
+ gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
+ GTK_SIGNAL_FUNC (set_style), NULL);
+
+ styles_combo = combo;
+ fill_styles_combo (combo);
+
+ return combo;
+}
+
+int
+cmp_strings (const void *a, const void *b)
+{
+ return strcmp (*(const char **)a, *(const char **)b);
+}
+
+GtkWidget *
+make_families_menu ()
+{
+ GtkWidget *combo;
+ gchar **families;
+ int n_families;
+ GList *family_list = NULL;
+ int i;
+
+ pango_context_list_families (context, &families, &n_families);
+ qsort (families, n_families, sizeof(char *), cmp_strings);
+
+ for (i=0; i<n_families; i++)
+ family_list = g_list_prepend (family_list, families[i]);
+
+ family_list = g_list_reverse (family_list);
combo = gtk_combo_new ();
- gtk_combo_set_popdown_strings (GTK_COMBO (combo), families);
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), family_list);
gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
gtk_editable_set_editable (GTK_EDITABLE (GTK_COMBO (combo)->entry), FALSE);
@@ -862,10 +1079,8 @@ make_families_menu ()
gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->entry), "changed",
GTK_SIGNAL_FUNC (set_family), NULL);
- g_hash_table_destroy (families_hash);
- g_list_free (families);
-
- pango_font_descriptions_free (descs, n_descs);
+ g_list_free (family_list);
+ pango_font_map_free_families (families, n_families);
return combo;
}
@@ -892,6 +1107,14 @@ make_font_selector (void)
gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0);
util_hbox = gtk_hbox_new (FALSE, 2);
+ label = gtk_label_new ("Style:");
+ gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0);
+ option_menu = make_styles_combo ();
+ gtk_box_pack_start (GTK_BOX (util_hbox), option_menu, FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (hbox), util_hbox, FALSE, FALSE, 0);
+
+ util_hbox = gtk_hbox_new (FALSE, 2);
label = gtk_label_new ("Size:");
gtk_box_pack_start (GTK_BOX (util_hbox), label, FALSE, FALSE, 0);
spin_button = gtk_spin_button_new (NULL, 1., 0);
diff --git a/pango/fonts.c b/pango/fonts.c
index a519daee..b52742aa 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -290,20 +290,62 @@ pango_font_map_load_font (PangoFontMap *fontmap,
/**
* pango_font_map_list_fonts:
* @fontmap: a #PangoFontMap
+ * @family: the family for which to list the fonts, or %NULL
+ * to list fonts in all families.
* @descs: location to store a pointer to an array of pointers to
* #PangoFontDescription. This array should be freed
* with pango_font_descriptions_free().
* @n_descs: location to store the number of elements in @descs
*
- * List all fonts in a fontmap.
+ * List all fonts in a fontmap, or the fonts in a particular family.
**/
void
pango_font_map_list_fonts (PangoFontMap *fontmap,
+ const char *family,
PangoFontDescription ***descs,
int *n_descs)
{
g_return_if_fail (fontmap != NULL);
- fontmap->klass->list_fonts (fontmap, descs, n_descs);
+ fontmap->klass->list_fonts (fontmap, family, descs, n_descs);
}
+/**
+ * pango_font_map_list_families:
+ * @fontmap: a #PangoFontMap
+ * @families: location to store a pointer to an array of strings.
+ * This array should be freed with pango_font_map_free_families().
+ * @n_families: location to store the number of elements in @descs
+ *
+ * List all families for a fontmap.
+ **/
+void
+pango_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families)
+{
+ g_return_if_fail (fontmap != NULL);
+
+ fontmap->klass->list_families (fontmap, families, n_families);
+}
+
+/**
+ * pango_font_map_free_families:
+ * @families: a list of families
+ * @n_families: number of elements in @families
+ *
+ * Free a list of families returned from pango_font_map_list_families()
+ **/
+void
+pango_font_map_free_families (gchar **families,
+ int n_families)
+{
+ int i;
+
+ g_return_if_fail (n_families == 0 || families != NULL);
+
+ for (i=0; i<n_families; i++)
+ g_free (families[i]);
+
+ g_free (families);
+}
diff --git a/pango/pango-context.c b/pango/pango-context.c
index 7a369a86..d9e15c3f 100644
--- a/pango/pango-context.c
+++ b/pango/pango-context.c
@@ -125,6 +125,7 @@ pango_context_add_font_map (PangoContext *context,
**/
void
pango_context_list_fonts (PangoContext *context,
+ const char *family,
PangoFontDescription ***descs,
int *n_descs)
{
@@ -133,21 +134,24 @@ pango_context_list_fonts (PangoContext *context,
g_return_if_fail (context != NULL);
g_return_if_fail (descs == NULL || n_descs != NULL);
- if (n_descs == NULL)
+ if (n_descs == 0)
return;
n_maps = g_slist_length (context->font_maps);
if (n_maps == 0)
{
- if (n_descs)
- *n_descs = 0;
+ *n_descs = 0;
+ if (descs)
+ *descs = NULL;
return;
}
else if (n_maps == 1)
- pango_font_map_list_fonts (context->font_maps->data, descs, n_descs);
+ pango_font_map_list_fonts (context->font_maps->data, family, descs, n_descs);
else
{
+ /* FIXME: This does not properly suppress duplicate fonts! */
+
PangoFontDescription ***tmp_descs;
int *tmp_n_descs;
int total_n_descs = 0;
@@ -162,7 +166,7 @@ pango_context_list_fonts (PangoContext *context,
tmp_list = context->font_maps;
for (i = 0; i<n_maps; i++)
{
- pango_font_map_list_fonts (tmp_list->data, &tmp_descs[i], &tmp_n_descs[i]);
+ pango_font_map_list_fonts (tmp_list->data, family, &tmp_descs[i], &tmp_n_descs[i]);
*n_descs += tmp_n_descs[i];
tmp_list = tmp_list->next;
@@ -191,6 +195,107 @@ pango_context_list_fonts (PangoContext *context,
}
}
+typedef struct
+{
+ int n_found;
+ char **families;
+} ListFamiliesInfo;
+
+static void
+list_families_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+ ListFamiliesInfo *info = user_data;
+
+ if (info->families)
+ info->families[info->n_found++] = value;
+
+ g_free (value);
+}
+
+/**
+ * pango_context_list_families:
+ * @fontmap: a #PangoContext
+ * @families: location to store a pointer to an array of strings.
+ * This array should be freed with pango_font_map_free_families().
+ * @n_families: location to store the number of elements in @descs
+ *
+ * List all families for a context.
+ **/
+void
+pango_context_list_families (PangoContext *context,
+ gchar ***families,
+ int *n_families)
+{
+ int n_maps;
+
+ g_return_if_fail (context != NULL);
+ g_return_if_fail (families == NULL || n_families != NULL);
+
+ if (n_families == NULL)
+ return;
+
+ n_maps = g_slist_length (context->font_maps);
+
+ if (n_maps == 0)
+ {
+ *n_families = 0;
+ if (families)
+ *families = NULL;
+
+ return;
+ }
+ else if (n_maps == 1)
+ pango_font_map_list_families (context->font_maps->data, families, n_families);
+ else
+ {
+ GHashTable *family_hash;
+ GSList *tmp_list;
+ ListFamiliesInfo info;
+
+ *n_families = 0;
+
+ family_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ tmp_list = context->font_maps;
+ while (tmp_list)
+ {
+ char **tmp_families;
+ int tmp_n_families;
+ int i;
+
+ pango_font_map_list_families (tmp_list->data, &tmp_families, &tmp_n_families);
+
+ for (i=0; i<*n_families; i++)
+ {
+ if (!g_hash_table_lookup (family_hash, tmp_families[i]))
+ {
+ char *family = g_strdup (tmp_families[i]);
+
+ g_hash_table_insert (family_hash, family, family);
+ (*n_families)++;
+ }
+ }
+
+ pango_font_map_free_families (tmp_families, tmp_n_families);
+
+ tmp_list = tmp_list->next;
+ }
+
+ info.n_found = 0;
+
+ if (families)
+ {
+ *families = g_new (char *, *n_families);
+ info.families = *families;
+ }
+ else
+ info.families = NULL;
+
+ g_hash_table_foreach (family_hash, list_families_foreach, &info);
+ g_hash_table_destroy (family_hash);
+ }
+}
+
/**
* pango_context_load_font:
* @context: a #PangoContext
diff --git a/pango/pango-context.h b/pango/pango-context.h
index 642f3d49..64fe06ac 100644
--- a/pango/pango-context.h
+++ b/pango/pango-context.h
@@ -41,8 +41,12 @@ void pango_context_add_font_map (PangoContext *context,
PangoFontMap *font_map);
void pango_context_list_fonts (PangoContext *context,
+ const char *family,
PangoFontDescription ***descs,
int *n_descs);
+void pango_context_list_families (PangoContext *context,
+ gchar ***families,
+ int *n_families);
PangoFont * pango_context_load_font (PangoContext *context,
PangoFontDescription *desc,
gdouble size);
diff --git a/pango/pango-font.h b/pango/pango-font.h
index a2d618ab..161236e6 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -130,24 +130,36 @@ struct _PangoFontMap
struct _PangoFontMapClass
{
- void (*destroy) (PangoFontMap *fontmap);
- PangoFont *(*load_font) (PangoFontMap *fontmap,
- PangoFontDescription *desc,
- double size);
- void (*list_fonts) (PangoFontMap *fontmap,
- PangoFontDescription ***descs,
- int *n_descs);
+ void (*destroy) (PangoFontMap *fontmap);
+ PangoFont *(*load_font) (PangoFontMap *fontmap,
+ PangoFontDescription *desc,
+ double size);
+ void (*list_fonts) (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+ void (*list_families) (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
};
-void pango_font_map_init (PangoFontMap *fontmap);
-void pango_font_map_ref (PangoFontMap *fontmap);
-void pango_font_map_unref (PangoFontMap *fontmap);
-PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
- PangoFontDescription *desc,
- double size);
-void pango_font_map_list_fonts (PangoFontMap *fontmap,
- PangoFontDescription ***descs,
- int *n_descs);
+void pango_font_map_init (PangoFontMap *fontmap);
+void pango_font_map_ref (PangoFontMap *fontmap);
+void pango_font_map_unref (PangoFontMap *fontmap);
+PangoFont *pango_font_map_load_font (PangoFontMap *fontmap,
+ PangoFontDescription *desc,
+ double size);
+
+void pango_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+void pango_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
+void pango_font_map_free_families (gchar **families,
+ int n_families);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/pango/pangox.c b/pango/pangox.c
index c0347080..bcc175d1 100644
--- a/pango/pangox.c
+++ b/pango/pangox.c
@@ -155,15 +155,18 @@ const struct {
{ "condensed", PANGO_STRETCH_CONDENSED },
};
-static void pango_x_font_map_destroy (PangoFontMap *fontmap);
-static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap,
- PangoFontDescription *desc,
- double size);
-static void pango_x_font_map_list_fonts (PangoFontMap *fontmap,
- PangoFontDescription ***descs,
- int *n_descs);
-static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);
-
+static void pango_x_font_map_destroy (PangoFontMap *fontmap);
+static PangoFont *pango_x_font_map_load_font (PangoFontMap *fontmap,
+ PangoFontDescription *desc,
+ double size);
+static void pango_x_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
+ PangoFontDescription ***descs,
+ int *n_descs);
+static void pango_x_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families);
+static void pango_x_font_map_read_aliases (PangoXFontMap *xfontmap);
static void pango_x_font_destroy (PangoFont *font);
static PangoFontDescription *pango_x_font_describe (PangoFont *font);
@@ -210,7 +213,8 @@ PangoFontClass pango_x_font_class = {
PangoFontMapClass pango_x_font_map_class = {
pango_x_font_map_destroy,
pango_x_font_map_load_font,
- pango_x_font_map_list_fonts
+ pango_x_font_map_list_fonts,
+ pango_x_font_map_list_families
};
static PangoFontMap *
@@ -350,7 +354,6 @@ typedef struct
PangoFontDescription **descs;
} ListFontsInfo;
-
static void
list_fonts_foreach (gpointer key, gpointer value, gpointer user_data)
{
@@ -370,6 +373,7 @@ list_fonts_foreach (gpointer key, gpointer value, gpointer user_data)
static void
pango_x_font_map_list_fonts (PangoFontMap *fontmap,
+ const gchar *family,
PangoFontDescription ***descs,
int *n_descs)
{
@@ -379,16 +383,84 @@ pango_x_font_map_list_fonts (PangoFontMap *fontmap,
if (!n_descs)
return;
- *n_descs = xfontmap->n_fonts;
- if (!descs)
+ if (family)
+ {
+ PangoXFamilyEntry *entry = g_hash_table_lookup (xfontmap->families, family);
+ if (entry)
+ {
+ *n_descs = g_slist_length (entry->font_entries);
+ if (descs)
+ {
+ *descs = g_new (PangoFontDescription *, *n_descs);
+
+ info.descs = *descs;
+ info.n_found = 0;
+
+ list_fonts_foreach ((gpointer)family, (gpointer)entry, &info);
+ }
+ }
+ else
+ {
+ *n_descs = 0;
+ if (descs)
+ *descs = NULL;
+ }
+ }
+ else
+ {
+ *n_descs = xfontmap->n_fonts;
+ if (descs)
+ {
+ *descs = g_new (PangoFontDescription *, xfontmap->n_fonts);
+
+ info.descs = *descs;
+ info.n_found = 0;
+
+ g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info);
+ }
+ }
+}
+
+static void
+list_families_foreach (gpointer key, gpointer value, gpointer user_data)
+{
+ GSList **list = user_data;
+
+ *list = g_slist_prepend (*list, key);
+}
+
+static void
+pango_x_font_map_list_families (PangoFontMap *fontmap,
+ gchar ***families,
+ int *n_families)
+{
+ GSList *family_list = NULL;
+ GSList *tmp_list;
+ PangoXFontMap *xfontmap = (PangoXFontMap *)fontmap;
+
+ if (!n_families)
return;
- *descs = g_new (PangoFontDescription *, xfontmap->n_fonts);
+ g_hash_table_foreach (xfontmap->families, list_families_foreach, &family_list);
+
+ *n_families = g_slist_length (family_list);
- info.descs = *descs;
- info.n_found = 0;
+ if (families)
+ {
+ int i = 0;
+
+ *families = g_new (gchar *, *n_families);
+
+ tmp_list = family_list;
+ while (tmp_list)
+ {
+ (*families)[i] = g_strdup (tmp_list->data);
+ i++;
+ tmp_list = tmp_list->next;
+ }
+ }
- g_hash_table_foreach (xfontmap->families, list_fonts_foreach, &info);
+ g_slist_free (family_list);
}
/* Similar to GNU libc's getline, but buffer is g_malloc'd */