/* * 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; }
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 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; }
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; }
FcStrList * FcConfigGetConfigFiles (FcConfig *config) { if (!config) { config = FcConfigGetCurrent (); if (!config) return 0; } return FcStrListCreate (config->configFiles); }
FcStrList * FcConfigGetCacheDirs (const FcConfig *config) { if (!config) { config = FcConfigGetCurrent (); if (!config) return 0; } return FcStrListCreate (config->cacheDirs); }
FcStrList * FcConfigGetFontDirs (FcConfig *config) { if (!config) { config = FcConfigGetCurrent (); if (!config) return 0; } return FcStrListCreate (config->fontDirs); }
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; }
FcStrSet *fcinfo_languages(const FcPattern *filter) { FcObjectSet *objectset; FcFontSet *fontset; FcLangSet *union_langset; FcStrSet *result; int f; FcInit(); objectset = FcObjectSetBuild(FC_LANG, NULL); fontset = FcFontList(NULL, (FcPattern *)filter, objectset); FcObjectSetDestroy(objectset); union_langset = FcLangSetCreate(); for (f = 0; f < fontset->nfont; f++) { FcLangSet *langset; FcStrList *strlist; FcChar8 *lang; if (FcPatternGetLangSet(fontset->fonts[f], FC_LANG, 0, &langset) != FcResultMatch) continue; if (! langset) continue; strlist = FcStrListCreate(FcLangSetGetLangs(langset)); while ((lang = FcStrListNext(strlist))) if (FcLangSetHasLang(union_langset, lang)) FcLangSetAdd(union_langset, FcStrCopy(lang)); } result = FcLangSetGetLangs(union_langset); FcFontSetDestroy(fontset); FcLangSetDestroy(union_langset); return result; }
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; }
int main (int argc, char **argv) { FcStrSet *dirs; FcStrList *list; FcBool verbose = FcFalse; FcBool force = FcFalse; FcBool really_force = FcFalse; FcBool systemOnly = FcFalse; FcConfig *config; int i; int changed; int ret; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "frsVvh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "frsVvh")) != -1) #endif { switch (c) { case 'r': really_force = FcTrue; /* fall through */ case 'f': force = FcTrue; break; case 's': systemOnly = FcTrue; 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); 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; } changed = 0; ret = scanDirs (list, config, force, really_force, verbose, &changed); /* * 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); /* * 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. */ FcConfigDestroy (config); FcFini (); if (changed) sleep (2); if (verbose) printf ("%s: %s\n", argv[0], ret ? "failed" : "succeeded"); return ret; }
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; }
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; } }