static FcBool cache_print_set (FcFontSet *set, FcStrSet *dirs, const FcChar8 *base_name, FcBool verbose) { FcChar8 *dir; const FcChar8 *base; int n; int ndir = 0; FcStrList *list; list = FcStrListCreate (dirs); if (!list) goto bail2; while ((dir = FcStrListNext (list))) { base = file_base_name (base_name, dir); if (!write_string (stdout, base)) goto bail3; if (PUTC (' ', stdout) == EOF) goto bail3; if (!write_int (stdout, 0)) goto bail3; if (PUTC (' ', stdout) == EOF) goto bail3; if (!write_string (stdout, FC_FONT_FILE_DIR)) goto bail3; if (PUTC ('\n', stdout) == EOF) goto bail3; ndir++; } for (n = 0; n < set->nfont; n++) { FcPattern *font = set->fonts[n]; FcChar8 *s; s = FcPatternFormat (font, (const FcChar8 *) "%{=fccat}\n"); if (s) { printf ("%s", s); FcStrFree (s); } } if (verbose && !set->nfont && !ndir) printf ("<empty>\n"); FcStrListDone (list); return FcTrue; bail3: FcStrListDone (list); bail2: return FcFalse; }
/* * Look for a cache file for the specified dir. Attempt * to use each one we find, stopping when the callback * indicates success */ static FcBool FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, FcBool (*callback) (FcConfig *config, int fd, struct stat *fd_stat, struct stat *dir_stat, void *closure), void *closure, FcChar8 **cache_file_ret) { int fd = -1; FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir, *d; struct stat file_stat, dir_stat; FcBool ret = FcFalse; const FcChar8 *sysroot = FcConfigGetSysRoot (config); if (sysroot) d = FcStrBuildFilename (sysroot, dir, NULL); else d = FcStrdup (dir); if (FcStatChecksum (d, &dir_stat) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); FcDirCacheBasename (dir, cache_base); list = FcStrListCreate (config->cacheDirs); if (!list) return FcFalse; while ((cache_dir = FcStrListNext (list))) { FcChar8 *cache_hashed; if (sysroot) cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); else cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) break; fd = FcDirCacheOpenFile (cache_hashed, &file_stat); if (fd >= 0) { ret = (*callback) (config, fd, &file_stat, &dir_stat, closure); close (fd); if (ret) { if (cache_file_ret) *cache_file_ret = cache_hashed; else FcStrFree (cache_hashed); break; } } FcStrFree (cache_hashed); } FcStrListDone (list); return ret; }
static void xfce_xsettings_helper_fc_monitor (XfceXSettingsHelper *helper, FcStrList *files) { const gchar *path; GFile *file; GFileMonitor *monitor; if (G_UNLIKELY (files == NULL)) return; for (;;) { path = (const gchar *) FcStrListNext (files); if (G_UNLIKELY (path == NULL)) break; file = g_file_new_for_path (path); monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); g_object_unref (G_OBJECT (file)); if (G_LIKELY (monitor != NULL)) { g_ptr_array_add (helper->fc_monitors, monitor); g_signal_connect_swapped (G_OBJECT (monitor), "changed", G_CALLBACK (xfce_xsettings_helper_fc_changed), helper); xfsettings_dbg_filtered (XFSD_DEBUG_FONTCONFIG, "monitoring \"%s\"", path); } } FcStrListDone (files); }
FcBool FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) { FcChar8 *cache_hashed = NULL; FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir; const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcDirCacheBasename (dir, cache_base); list = FcStrListCreate (config->cacheDirs); if (!list) return FcFalse; while ((cache_dir = FcStrListNext (list))) { if (sysroot) cache_hashed = FcStrBuildFilename (sysroot, cache_dir, cache_base, NULL); else cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) break; (void) unlink ((char *) cache_hashed); FcStrFree (cache_hashed); } FcStrListDone (list); /* return FcFalse if something went wrong */ if (cache_dir) return FcFalse; return FcTrue; }
static void monitor_files (GPtrArray *monitors, FcStrList *list, gpointer data) { const char *str; while ((str = (const char *) FcStrListNext (list))) { GFile *file; GFileMonitor *monitor; file = g_file_new_for_path (str); monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); g_object_unref (file); if (!monitor) continue; g_signal_connect (monitor, "changed", G_CALLBACK (stuff_changed), data); g_ptr_array_add (monitors, monitor); } FcStrListDone (list); }
static void create_file_monitors (FontViewModel *self) { FcConfig *config; FcStrList *str_list; FcChar8 *path; GFile *file; GFileMonitor *monitor; config = FcConfigGetCurrent (); str_list = FcConfigGetFontDirs (config); while ((path = FcStrListNext (str_list)) != NULL) { file = g_file_new_for_path ((const gchar *) path); monitor = g_file_monitor (file, G_FILE_MONITOR_NONE, NULL, NULL); if (monitor != NULL) { self->priv->monitors = g_list_prepend (self->priv->monitors, monitor); g_signal_connect (monitor, "changed", G_CALLBACK (file_monitor_changed_cb), self); } g_object_unref (file); } FcStrListDone (str_list); }
static FcBool FcConfigAddDirList (FcConfig *config, FcSetName set, FcStrSet *dirSet) { FcStrList *dirlist; FcChar8 *dir; FcCache *cache; FcBool ret = FcFalse; dirlist = FcStrListCreate (dirSet); if (!dirlist) return FcFalse; while ((dir = FcStrListNext (dirlist))) { if (FcDebug () & FC_DBG_FONTSET) printf ("adding fonts from %s\n", dir); cache = FcDirCacheRead (dir, FcFalse, config); if (!cache) continue; FcConfigAddCache (config, cache, set, dirSet); FcDirCacheUnload (cache); ret = FcTrue; } FcStrListDone (dirlist); return ret; }
GeeArrayList * FcListUserDirs(void) { FcChar8 * directory; FcStrList * fdlist; GeeArrayList * dirlist = gee_array_list_new(G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free0, NULL, NULL, NULL); g_assert(FcInit()); fdlist = FcConfigGetConfigDirs(NULL); while ((directory = FcStrListNext(fdlist))) if (get_file_owner((const gchar *) directory) == 0) gee_abstract_collection_add((GeeAbstractCollection *) dirlist, directory); FcStrListDone(fdlist); return dirlist; }
static FcBool cleanCacheDirectories (FcConfig *config, FcBool verbose) { FcStrList *cache_dirs = FcConfigGetCacheDirs (config); FcChar8 *cache_dir; FcBool ret = FcTrue; if (!cache_dirs) return FcFalse; while ((cache_dir = FcStrListNext (cache_dirs))) { if (!FcDirCacheClean (cache_dir, verbose)) { ret = FcFalse; break; } } FcStrListDone (cache_dirs); return ret; }
GeeArrayList * FcListDirs(gboolean recursive) { FcChar8 * directory; FcStrList * fdlist; GeeArrayList * dirlist = gee_array_list_new(G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free0, NULL, NULL, NULL); g_assert(FcInit()); if (recursive) fdlist = FcConfigGetFontDirs(NULL); else fdlist = FcConfigGetConfigDirs(NULL); while ((directory = FcStrListNext(fdlist))) gee_abstract_collection_add((GeeAbstractCollection *) dirlist, directory); FcStrListDone(fdlist); return dirlist; }
static FcFileTime FcConfigNewestFile (FcStrSet *files) { FcStrList *list = FcStrListCreate (files); FcFileTime newest = { 0, FcFalse }; FcChar8 *file; struct stat statb; if (list) { while ((file = FcStrListNext (list))) if (FcStat (file, &statb) == 0) if (!newest.set || statb.st_mtime - newest.time > 0) { newest.set = FcTrue; newest.time = statb.st_mtime; } FcStrListDone (list); } return newest; }
int main (int argc, char **argv) { int brief = 0; FcChar8 *format = NULL; int i; FcFontSet *fs; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "bf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "bf:Vh")) != -1) #endif { switch (c) { case 'b': brief = 1; break; case 'f': format = (FcChar8 *) strdup (optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (i == argc) usage (argv[0], 1); fs = FcFontSetCreate (); for (; i < argc; i++) { const FcChar8 *file = (FcChar8*) argv[i]; if (!FcFileIsDir (file)) FcFileScan (fs, NULL, NULL, NULL, file, FcTrue); else { FcStrSet *dirs = FcStrSetCreate (); FcStrList *strlist = FcStrListCreate (dirs); do { FcDirScan (fs, dirs, NULL, NULL, file, FcTrue); } while ((file = FcStrListNext (strlist))); FcStrListDone (strlist); FcStrSetDestroy (dirs); } } for (i = 0; i < fs->nfont; i++) { FcPattern *pat = fs->fonts[i]; if (brief) { FcPatternDel (pat, FC_CHARSET); FcPatternDel (pat, FC_LANG); } if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); FcStrFree (s); } } else { FcPatternPrint (pat); } } FcFontSetDestroy (fs); FcFini (); return i > 0 ? 0 : 1; }
int main (int argc, char **argv) { int i; int ret = 0; FcFontSet *fs; FcStrSet *dirs; FcStrSet *args = NULL; FcStrList *arglist; FcCache *cache; FcConfig *config; FcChar8 *arg; int verbose = 0; int recurse = 0; FcBool first = FcTrue; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "Vvrh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "Vvrh")) != -1) #endif { switch (c) { case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'v': verbose++; break; case 'r': recurse++; break; case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif config = FcInitLoadConfig (); if (!config) { fprintf (stderr, "%s: Can't init font config library\n", argv[0]); return 1; } FcConfigSetCurrent (config); args = FcStrSetCreate (); if (!args) { fprintf (stderr, "%s: malloc failure\n", argv[0]); return 1; } if (i < argc) { for (; i < argc; i++) { if (!FcStrSetAddFilename (args, (const FcChar8 *) argv[i])) { fprintf (stderr, "%s: malloc failure\n", argv[0]); return 1; } } arglist = FcStrListCreate (args); if (!arglist) { fprintf (stderr, "%s: malloc failure\n", argv[0]); return 1; } } else { recurse++; arglist = FcConfigGetFontDirs (config); while ((arg = FcStrListNext (arglist))) if (!FcStrSetAdd (args, arg)) { fprintf (stderr, "%s: malloc failure\n", argv[0]); return 1; } FcStrListDone (arglist); } arglist = FcStrListCreate (args); if (!arglist) { fprintf (stderr, "%s: malloc failure\n", argv[0]); return 1; } while ((arg = FcStrListNext (arglist))) { int j; FcChar8 *cache_file = NULL; struct stat file_stat; if (FcFileIsDir (arg)) cache = FcDirCacheLoad (arg, config, &cache_file); else cache = FcDirCacheLoadFile (arg, &file_stat); if (!cache) { perror ((char *) arg); ret++; continue; } dirs = FcStrSetCreate (); fs = FcCacheCopySet (cache); for (j = 0; j < FcCacheNumSubdir (cache); j++) { FcStrSetAdd (dirs, FcCacheSubdir (cache, j)); if (recurse) FcStrSetAdd (args, FcCacheSubdir (cache, j)); } if (verbose) { if (!first) printf ("\n"); printf ("Directory: %s\nCache: %s\n--------\n", FcCacheDir(cache), cache_file ? cache_file : arg); first = FcFalse; } cache_print_set (fs, dirs, FcCacheDir (cache), verbose); FcStrSetDestroy (dirs); FcFontSetDestroy (fs); FcDirCacheUnload (cache); if (cache_file) FcStrFree (cache_file); } FcFini (); return 0; }
static int scanDirs (FcStrList *list, FcConfig *config, FcBool force, FcBool really_force, FcBool verbose, int *changed) { int ret = 0; const FcChar8 *dir; FcStrSet *subdirs; FcStrList *sublist; FcCache *cache; struct stat statb; FcBool was_valid; int i; /* * Now scan all of the directories into separate databases * and write out the results */ while ((dir = FcStrListNext (list))) { if (verbose) { printf ("%s: ", dir); fflush (stdout); } if (!dir) { if (verbose) printf ("skipping, no such directory\n"); continue; } if (FcStrSetMember (processed_dirs, dir)) { if (verbose) printf ("skipping, looped directory detected\n"); continue; } if (stat ((char *) dir, &statb) == -1) { switch (errno) { case ENOENT: case ENOTDIR: if (verbose) printf ("skipping, no such directory\n"); break; default: fprintf (stderr, "\"%s\": ", dir); perror (""); ret++; break; } continue; } if (!S_ISDIR (statb.st_mode)) { fprintf (stderr, "\"%s\": not a directory, skipping\n", dir); continue; } if (really_force) FcDirCacheUnlink (dir, config); cache = NULL; was_valid = FcFalse; if (!force) { cache = FcDirCacheLoad (dir, config, NULL); if (cache) was_valid = FcTrue; } if (!cache) { (*changed)++; cache = FcDirCacheRead (dir, FcTrue, config); if (!cache) { fprintf (stderr, "%s: error scanning\n", dir); ret++; continue; } } if (was_valid) { if (verbose) printf ("skipping, existing cache is valid: %d fonts, %d dirs\n", FcCacheNumFont (cache), FcCacheNumSubdir (cache)); } else { if (verbose) printf ("caching, new cache contents: %d fonts, %d dirs\n", FcCacheNumFont (cache), FcCacheNumSubdir (cache)); if (!FcDirCacheValid (dir)) { fprintf (stderr, "%s: failed to write cache\n", dir); (void) FcDirCacheUnlink (dir, config); ret++; } } subdirs = FcStrSetCreate (); if (!subdirs) { fprintf (stderr, "%s: Can't create subdir set\n", dir); ret++; FcDirCacheUnload (cache); continue; } for (i = 0; i < FcCacheNumSubdir (cache); i++) FcStrSetAdd (subdirs, FcCacheSubdir (cache, i)); FcDirCacheUnload (cache); sublist = FcStrListCreate (subdirs); FcStrSetDestroy (subdirs); if (!sublist) { fprintf (stderr, "%s: Can't create subdir list\n", dir); ret++; continue; } FcStrSetAdd (processed_dirs, dir); ret += scanDirs (sublist, config, force, really_force, verbose, changed); } FcStrListDone (list); return ret; }
int main (int argc, char **argv) { FcStrSet *dirs, *updateDirs; FcStrList *list; FcBool verbose = FcFalse; FcBool force = FcFalse; FcBool really_force = FcFalse; FcBool systemOnly = FcFalse; FcBool error_on_no_fonts = FcFalse; FcConfig *config; FcChar8 *sysroot = NULL; int i; int changed; int ret; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "Efrsy:Vvh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "Efrsy:Vvh")) != -1) #endif { switch (c) { case 'E': error_on_no_fonts = FcTrue; break; case 'r': really_force = FcTrue; /* fall through */ case 'f': force = FcTrue; break; case 's': systemOnly = FcTrue; break; case 'y': sysroot = FcStrCopy ((const FcChar8 *)optarg); break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); exit (0); case 'v': verbose = FcTrue; break; case 'h': usage (argv[0], 0); default: usage (argv[0], 1); } } i = optind; #else i = 1; #endif if (systemOnly) FcConfigEnableHome (FcFalse); if (sysroot) { FcConfigSetSysRoot (NULL, sysroot); FcStrFree (sysroot); config = FcConfigGetCurrent(); } else { config = FcInitLoadConfig (); } if (!config) { fprintf (stderr, "%s: Can't init font config library\n", argv[0]); return 1; } FcConfigSetCurrent (config); if (argv[i]) { dirs = FcStrSetCreate (); if (!dirs) { fprintf (stderr, "%s: Can't create list of directories\n", argv[0]); return 1; } while (argv[i]) { if (!FcStrSetAddFilename (dirs, (FcChar8 *) argv[i])) { fprintf (stderr, "%s: Can't add directory\n", argv[0]); return 1; } i++; } list = FcStrListCreate (dirs); FcStrSetDestroy (dirs); } else list = FcConfigGetConfigDirs (config); if ((processed_dirs = FcStrSetCreate()) == NULL) { fprintf(stderr, "Cannot malloc\n"); return 1; } updateDirs = FcStrSetCreate (); changed = 0; ret = scanDirs (list, config, force, really_force, verbose, FcTrue, error_on_no_fonts, &changed, updateDirs); /* Update the directory cache again to avoid the race condition as much as possible */ FcStrListDone (list); list = FcStrListCreate (updateDirs); if (list) { ret += scanDirs (list, config, FcTrue, FcFalse, verbose, FcFalse, error_on_no_fonts, &changed, NULL); FcStrListDone (list); } FcStrSetDestroy (updateDirs); /* * Try to create CACHEDIR.TAG anyway. * This expects the fontconfig cache directory already exists. * If it doesn't, it won't be simply created. */ FcCacheCreateTagFile (config); FcStrSetDestroy (processed_dirs); cleanCacheDirectories (config, verbose); FcConfigDestroy (config); FcFini (); /* * Now we need to sleep a second (or two, to be extra sure), to make * sure that timestamps for changes after this run of fc-cache are later * then any timestamps we wrote. We don't use gettimeofday() because * sleep(3) can't be interrupted by a signal here -- this isn't in the * library, and there aren't any signals flying around here. */ /* the resolution of mtime on FAT is 2 seconds */ if (changed) sleep (2); if (verbose) printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded"); return ret; }
void font_config_magic_class:: add_entry(FcPattern *p) { FcMagicValue<FcChar8*> family_name, file_name, foundary_name, font_style; FcMagicValue<int> font_index, font_weight, font_slant; FcMagicValue<FcLangSet*> lang; FcGetMagicValue(p, FC_FILE, file_name); if(file_name.m_exists) { FontEntry entry_key; WRATHFontConfig::FontSpecification entry; GetPairFromFcMagicValue(entry_key.m_filename, file_name); FcGetMagicValue(p, FC_INDEX, font_index); GetPairFromFcMagicValue(entry_key.m_face_index, font_index); entry.font()=WRATHFontDatabase::fetch_font_entry(entry_key.m_filename, entry_key.m_face_index); FcGetMagicValue(p, FC_FAMILY, family_name); GetPairFromFcMagicValue(entry.m_fontconfig_details.m_family_name, family_name); FcGetMagicValue(p, FC_FOUNDRY, foundary_name); GetPairFromFcMagicValue(entry.m_fontconfig_details.m_foundary_name, foundary_name); FcGetMagicValue(p, FC_WEIGHT, font_weight); GetPairFromFcMagicValue(entry.m_fontconfig_details.m_weight, font_weight); FcGetMagicValue(p, FC_SLANT, font_slant); GetPairFromFcMagicValue(entry.m_fontconfig_details.m_slant, font_slant); FcGetMagicValue(p, FC_STYLE, font_style); GetPairFromFcMagicValue(entry.m_fontconfig_details.m_style, font_style); #if (FC_MAJOR>=2 && FC_MINOR>=7) || (FC_MAJOR>=3) { FcGetMagicValue(p, FC_LANG, lang); if(lang.m_exists) { FcStrSet *langs_as_strs; FcStrList *iter; FcChar8 *current; langs_as_strs=FcLangSetGetLangs(lang.m_value); //do we need to free this thing?? iter=FcStrListCreate(langs_as_strs); for(current=FcStrListNext(iter); current; current=FcStrListNext(iter)) { const char *str(reinterpret_cast<const char*>(current)); entry.m_fontconfig_details.m_languages.insert(std::string(str)); } FcStrListDone(iter); FcStrSetDestroy(langs_as_strs); } } #endif WRATHassert(m_font_list.find(entry.font())==m_font_list.end()); m_font_list[entry.font()]=entry; } }