diff options
author | Owen Taylor <otaylor@redhat.com> | 2000-02-11 06:14:28 +0000 |
---|---|---|
committer | Owen Taylor <otaylor@src.gnome.org> | 2000-02-11 06:14:28 +0000 |
commit | b1c021842d26d5674a51f802f29e2a8496767c55 (patch) | |
tree | 58e8cf4cbaa464eaf728fc38e7aa1bbfb1cb24c3 | |
parent | 11884d20295c2aea6dfeb8a915dd02b48ec60d9c (diff) | |
download | pango-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-- | ChangeLog | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-0 | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-10 | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-2 | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-4 | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-6 | 10 | ||||
-rw-r--r-- | ChangeLog.pre-1-8 | 10 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | docs/tmpl/coverage-maps.sgml | 10 | ||||
-rw-r--r-- | examples/viewer.c | 259 | ||||
-rw-r--r-- | pango/fonts.c | 46 | ||||
-rw-r--r-- | pango/pango-context.c | 115 | ||||
-rw-r--r-- | pango/pango-context.h | 4 | ||||
-rw-r--r-- | pango/pango-font.h | 44 | ||||
-rw-r--r-- | pango/pangox.c | 106 |
15 files changed, 594 insertions, 63 deletions
@@ -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. @@ -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 */ |