From 16ba47a34005f390370f64a108c4b4acce8a9875 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sat, 23 Dec 2017 14:30:45 -0500 Subject: Add api to get language coverage for faces This is needed to make filtering in the font chooser performant. --- pango/fonts.c | 16 ++++++++++ pango/pango-font.h | 9 +++++- pango/pangofc-fontmap.c | 81 +++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/pango/fonts.c b/pango/fonts.c index d9a07c0b..31aa8fb2 100644 --- a/pango/fonts.c +++ b/pango/fonts.c @@ -2261,3 +2261,19 @@ pango_font_face_list_sizes (PangoFontFace *face, *n_sizes = 0; } } + +void +pango_font_face_get_languages (PangoFontFace *face, + PangoLanguage ***languages, + int *n_languages) +{ + g_return_if_fail (PANGO_IS_FONT_FACE (face)); + + if (PANGO_FONT_FACE_GET_CLASS (face)->get_languages != NULL) + PANGO_FONT_FACE_GET_CLASS (face)->get_languages (face, languages, n_languages); + else + { + *languages = NULL; + *n_languages = 0; + } +} diff --git a/pango/pango-font.h b/pango/pango-font.h index 4af31a95..9a0b22a9 100644 --- a/pango/pango-font.h +++ b/pango/pango-font.h @@ -492,6 +492,11 @@ void pango_font_face_list_sizes (PangoFontFace *face, PANGO_AVAILABLE_IN_1_18 gboolean pango_font_face_is_synthesized (PangoFontFace *face) G_GNUC_PURE; +PANGO_AVAILABLE_IN_1_42 +void pango_font_face_get_languages (PangoFontFace *face, + PangoLanguage ***languages, + int *n_languages); + #ifdef PANGO_ENABLE_BACKEND #define PANGO_FONT_FACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FONT_FACE, PangoFontFaceClass)) @@ -525,10 +530,12 @@ struct _PangoFontFaceClass gboolean (*is_synthesized) (PangoFontFace *face); /*< private >*/ + void (*get_languages) (PangoFontFace *face, + PangoLanguage ***languages, + int *n_languages); /* Padding for future expansion */ void (*_pango_reserved3) (void); - void (*_pango_reserved4) (void); }; #endif /* PANGO_ENABLE_BACKEND */ diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 4e7d74bb..6330045c 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -172,6 +172,8 @@ struct _PangoFcFace PangoFcFamily *family; char *style; + PangoLanguage **languages; + int n_languages; guint fake : 1; }; @@ -2513,12 +2515,24 @@ pango_fc_face_is_synthesized (PangoFontFace *face) return fcface->fake; } +static void +pango_fc_face_get_languages (PangoFontFace *face, + PangoLanguage ***languages, + int *n_languages) +{ + PangoFcFace *fcface = PANGO_FC_FACE (face); + + *languages = fcface->languages; + *n_languages = fcface->n_languages; +} + static void pango_fc_face_finalize (GObject *object) { PangoFcFace *fcface = PANGO_FC_FACE (object); g_free (fcface->style); + g_free (fcface->languages); G_OBJECT_CLASS (pango_fc_face_parent_class)->finalize (object); } @@ -2539,6 +2553,7 @@ pango_fc_face_class_init (PangoFcFaceClass *class) class->get_face_name = pango_fc_face_get_face_name; class->list_sizes = pango_fc_face_list_sizes; class->is_synthesized = pango_fc_face_is_synthesized; + class->get_languages = pango_fc_face_get_languages; } @@ -2552,16 +2567,46 @@ G_DEFINE_TYPE (PangoFcFamily, pango_fc_family, PANGO_TYPE_FONT_FAMILY); static PangoFcFace * create_face (PangoFcFamily *fcfamily, const char *style, - gboolean fake) + gboolean fake, + PangoLanguage **languages, + int n_languages) { PangoFcFace *face = g_object_new (PANGO_FC_TYPE_FACE, NULL); face->style = g_strdup (style); face->family = fcfamily; face->fake = fake; + face->languages = g_memdup (languages, sizeof (PangoLanguage *) * n_languages); + face->n_languages = n_languages; return face; } +static void +pango_languages_from_langset (FcLangSet *ls, + PangoLanguage ***languages, + int *n_languages) +{ + GPtrArray *array; + FcStrSet *ss; + FcStrList *sl; + char *s; + + array = g_ptr_array_new (); + + ss = FcLangSetGetLangs (ls); + sl = FcStrListCreate (ss); + FcStrListFirst (sl); + + while ((s = FcStrListNext (sl))) + g_ptr_array_add (array, pango_language_from_string (s)); + + FcStrListDone (sl); + FcStrSetDestroy (ss); + + *n_languages = array->len; + *languages = g_ptr_array_free (array, FALSE); +} + static void pango_fc_family_list_faces (PangoFontFamily *family, PangoFontFace ***faces, @@ -2589,14 +2634,14 @@ pango_fc_family_list_faces (PangoFontFamily *family, fcfamily->faces = g_new (PangoFcFace *, fcfamily->n_faces); i = 0; - fcfamily->faces[i++] = create_face (fcfamily, "Regular", TRUE); - fcfamily->faces[i++] = create_face (fcfamily, "Bold", TRUE); - fcfamily->faces[i++] = create_face (fcfamily, "Italic", TRUE); - fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic", TRUE); + fcfamily->faces[i++] = create_face (fcfamily, "Regular", TRUE, NULL, 0); + fcfamily->faces[i++] = create_face (fcfamily, "Bold", TRUE, NULL, 0); + fcfamily->faces[i++] = create_face (fcfamily, "Italic", TRUE, NULL, 0); + fcfamily->faces[i++] = create_face (fcfamily, "Bold Italic", TRUE, NULL, 0); } else { - FcObjectSet *os = FcObjectSetBuild (FC_STYLE, FC_WEIGHT, FC_SLANT, NULL); + FcObjectSet *os = FcObjectSetBuild (FC_STYLE, FC_WEIGHT, FC_SLANT, FC_LANG, NULL); FcPattern *pat = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, fcfamily->family_name, NULL); @@ -2624,6 +2669,9 @@ pango_fc_family_list_faces (PangoFontFamily *family, { const char *style, *font_style = NULL; int weight, slant; + FcLangSet *ls; + PangoLanguage **languages; + int n_languages; if (FcPatternGetInteger(fontset->fonts[i], FC_WEIGHT, 0, &weight) != FcResultMatch) weight = FC_WEIGHT_MEDIUM; @@ -2634,6 +2682,16 @@ pango_fc_family_list_faces (PangoFontFamily *family, if (FcPatternGetString (fontset->fonts[i], FC_STYLE, 0, (FcChar8 **)(void*)&font_style) != FcResultMatch) font_style = NULL; + if (FcPatternGetLangSet (fontset->fonts[i], FC_LANG, 0, &ls) != FcResultMatch) + { + languages = NULL; + n_languages = 0; + } + else + { + pango_languages_from_langset (ls, &languages, &n_languages); + } + if (weight <= FC_WEIGHT_MEDIUM) { if (slant == FC_SLANT_ROMAN) @@ -2663,19 +2721,22 @@ pango_fc_family_list_faces (PangoFontFamily *family, if (!font_style) font_style = style; - faces[num++] = create_face (fcfamily, font_style, FALSE); + + faces[num++] = create_face (fcfamily, font_style, FALSE, languages, n_languages); + + g_free (languages); } if (has_face[REGULAR]) { if (!has_face[ITALIC]) - faces[num++] = create_face (fcfamily, "Italic", TRUE); + faces[num++] = create_face (fcfamily, "Italic", TRUE, NULL, 0); if (!has_face[BOLD]) - faces[num++] = create_face (fcfamily, "Bold", TRUE); + faces[num++] = create_face (fcfamily, "Bold", TRUE, NULL, 0); } if ((has_face[REGULAR] || has_face[ITALIC] || has_face[BOLD]) && !has_face[BOLD_ITALIC]) - faces[num++] = create_face (fcfamily, "Bold Italic", TRUE); + faces[num++] = create_face (fcfamily, "Bold Italic", TRUE, NULL, 0); faces = g_renew (PangoFcFace *, faces, num); -- cgit v1.2.1