+ if (! ft_font_list)
+ {
+ MSymbol sym;
+
+ plist = ft_font_list = mplist ();
+ pattern = FcPatternCreate ();
+ os = FcObjectSetBuild (FC_FAMILY, NULL);
+ fs = FcFontList (fc_config, pattern, os);
+ for (i = 0; i < fs->nfont; i++)
+ {
+ if (FcPatternGetString (fs->fonts[i], FC_FAMILY, 0,
+ (FcChar8 **) &fam) != FcResultMatch)
+ continue;
+ STRDUP_LOWER (buf, bufsize, fam);
+ sym = msymbol (buf);
+ if (! mplist_find_by_key (ft_font_list, sym))
+ plist = mplist_add (plist, sym, NULL);
+ }
+ FcFontSetDestroy (fs);
+ FcObjectSetDestroy (os);
+ FcPatternDestroy (pattern);
+ }
+
+ if (family == Mnil)
+ {
+ if (! all_fonts_scaned)
+ {
+ MPLIST_DO (plist, ft_font_list)
+ {
+ if (! MPLIST_VAL (plist))
+ ft_list_family (MPLIST_KEY (plist), 0);
+ }
+ all_fonts_scaned = 1;
+ }
+ return ft_font_list;
+ }
+
+ plist = mplist_find_by_key (ft_font_list, family);
+ if (plist)
+ {
+ if (! MPLIST_VAL (plist))
+ {
+ fam = MSYMBOL_NAME (family);
+ pattern = FcPatternCreate ();
+ FcPatternAddString (pattern, FC_FAMILY, (FcChar8 *) fam);
+ os = FcObjectSetBuild (FC_FOUNDRY, FC_WEIGHT, FC_SLANT, FC_WIDTH,
+ FC_PIXEL_SIZE, FC_FILE, NULL);
+ fs = FcFontList (fc_config, pattern, os);
+ p = pl = mplist ();
+ for (i = 0; i < fs->nfont; i++)
+ {
+ MFontFT *ft_info = fc_gen_font (fs->fonts[i], fam);
+ p = mplist_add (p, ft_info->font.file, ft_info);
+ }
+ MPLIST_VAL (plist) = pl;
+ FcFontSetDestroy (fs);
+ FcObjectSetDestroy (os);
+ FcPatternDestroy (pattern);
+ }
+ }
+ else if (check_generic
+ && (generic = msymbol_get (family, Mgeneric_family)) != Mnil)
+ {
+ /* Check if FAMILY is a geneneric family (e.g. `serif'). */
+ FcChar8 *fam8;
+
+ if (family != generic)
+ plist = ft_list_family (generic, 1);
+ else
+ {
+ fam = MSYMBOL_NAME (family);
+ plist = mplist ();
+ mplist_push (ft_font_list, family, plist);
+ pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, fam, NULL);
+ FcConfigSubstitute (fc_config, pattern, FcMatchPattern);
+ for (i = 0; 1; i++)
+ {
+ if (FcPatternGetString (pattern, FC_FAMILY, i, &fam8)
+ != FcResultMatch)
+ break;
+ STRDUP_LOWER (buf, bufsize, (char *) fam8);
+ family = msymbol (buf);
+ if (msymbol_get (family, Mgeneric_family))
+ break;
+ pl = ft_list_family (family, 0);
+ if (! pl)
+ continue;
+ MPLIST_DO (pl, MPLIST_PLIST (pl))
+ plist = mplist_add (plist, Mt, MPLIST_VAL (pl));
+ }
+ plist = ft_font_list;
+ }
+ }
+ else
+ plist = mplist_add (ft_font_list, family, mplist ());
+
+#else /* not HAVE_FONTCONFIG */
+
+ if (! all_fonts_scaned)