/* * 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 FcBool FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) { struct stat dir_static; if (!dir_stat) { const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; if (sysroot) d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); else d = FcStrdup (FcCacheDir (cache)); if (FcStatChecksum (d, &dir_static) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); dir_stat = &dir_static; } if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); return cache->checksum == (int) dir_stat->st_mtime; }
/* * Load the configuration files */ FcConfig * FcInitLoadOwnConfig (FcConfig *config) { if (!config) { config = FcConfigCreate (); if (!config) return NULL; } FcInitDebug (); if (!FcConfigParseAndLoad (config, 0, FcTrue)) { FcConfigDestroy (config); return FcInitFallbackConfig (); } if (config->cacheDirs && config->cacheDirs->num == 0) { FcChar8 *prefix, *p; size_t plen; fprintf (stderr, "Fontconfig warning: no <cachedir> elements found. Check configuration.\n"); fprintf (stderr, "Fontconfig warning: adding <cachedir>%s</cachedir>\n", FC_CACHEDIR); prefix = FcConfigXdgCacheHome (); if (!prefix) goto bail; plen = strlen ((const char *)prefix); p = realloc (prefix, plen + 12); if (!p) goto bail; prefix = p; memcpy (&prefix[plen], FC_DIR_SEPARATOR_S "fontconfig", 11); prefix[plen + 11] = 0; fprintf (stderr, "Fontconfig warning: adding <cachedir prefix=\"xdg\">fontconfig</cachedir>\n"); if (!FcConfigAddCacheDir (config, (FcChar8 *) FC_CACHEDIR) || !FcConfigAddCacheDir (config, (FcChar8 *) prefix)) { bail: fprintf (stderr, "Fontconfig error: out of memory"); if (prefix) FcStrFree (prefix); FcConfigDestroy (config); return FcInitFallbackConfig (); } FcStrFree (prefix); } return config; }
int main (int argc, char **argv) { FcConfig *config; FcConfigFileInfoIter iter; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "Vh")) != -1) #endif { switch (c) { 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); } } #endif config = FcConfigGetCurrent (); FcConfigFileInfoIterInit (config, &iter); do { FcChar8 *name, *desc; FcBool enabled; if (FcConfigFileInfoIterGet (config, &iter, &name, &desc, &enabled)) { printf ("%c %s: %s\n", enabled ? '+' : '-', name, desc); FcStrFree (name); FcStrFree (desc); } } while (FcConfigFileInfoIterNext (config, &iter)); FcFini (); return 0; }
static FcBool FcCacheDirsValid (FcConfig *config, FcCache *cache) { FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); FcBool ret = FcFalse; const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; if (!dirs) goto bail; if (sysroot) d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); else d = FcStrdup (FcCacheDir (cache)); if (!FcDirScanOnly (dirs, d, config)) goto bail1; ret = cache->dirs_count == dirs->num; if (FcDebug () & FC_DBG_CACHE) printf ("%s: cache: %d, fs: %d\n", d, cache->dirs_count, dirs->num); bail1: FcStrSetDestroy (dirs); FcStrFree (d); bail: 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 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; }
FcBool FcConfigAddConfigFile (FcConfig *config, const FcChar8 *f) { FcBool ret; FcChar8 *file = FcConfigFilename (f); if (!file) return FcFalse; ret = FcStrSetAdd (config->configFiles, file); FcStrFree (file); return ret; }
static FcBool FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) { struct stat dir_static; FcBool fnano = FcTrue; if (!dir_stat) { const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; if (sysroot) d = FcStrBuildFilename (sysroot, FcCacheDir (cache), NULL); else d = FcStrdup (FcCacheDir (cache)); if (FcStatChecksum (d, &dir_static) < 0) { FcStrFree (d); return FcFalse; } FcStrFree (d); dir_stat = &dir_static; } #ifdef HAVE_STRUCT_STAT_ST_MTIM fnano = (cache->checksum_nano == dir_stat->st_mtim.tv_nsec); if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d.%ld dir checksum %d.%ld\n", FcCacheDir (cache), cache->checksum, (long)cache->checksum_nano, (int) dir_stat->st_mtime, dir_stat->st_mtim.tv_nsec); #else if (FcDebug () & FC_DBG_CACHE) printf ("FcCacheTimeValid dir \"%s\" cache checksum %d dir checksum %d\n", FcCacheDir (cache), cache->checksum, (int) dir_stat->st_mtime); #endif return cache->checksum == (int) dir_stat->st_mtime && fnano; }
void FcConfigDestroy (FcConfig *config) { FcSetName set; FcExprPage *page; if (FcRefDec (&config->ref) != 1) return; (void) fc_atomic_ptr_cmpexch (&_fcConfig, config, NULL); FcStrSetDestroy (config->configDirs); FcStrSetDestroy (config->fontDirs); FcStrSetDestroy (config->cacheDirs); FcStrSetDestroy (config->configFiles); FcStrSetDestroy (config->acceptGlobs); FcStrSetDestroy (config->rejectGlobs); FcFontSetDestroy (config->acceptPatterns); FcFontSetDestroy (config->rejectPatterns); if (config->blanks) FcBlanksDestroy (config->blanks); FcSubstDestroy (config->substPattern); FcSubstDestroy (config->substFont); FcSubstDestroy (config->substScan); for (set = FcSetSystem; set <= FcSetApplication; set++) if (config->fonts[set]) FcFontSetDestroy (config->fonts[set]); page = config->expr_pool; while (page) { FcExprPage *next = page->next_page; free (page); page = next; } if (config->sysRoot) FcStrFree (config->sysRoot); free (config); }
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) { int verbose = 0; int sort = 0, all = 0; const FcChar8 *format = NULL; int i; FcObjectSet *os = 0; FcFontSet *fs; FcPattern *pat; FcResult result; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "asvf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "asvf:Vh")) != -1) #endif { switch (c) { case 'a': all = 1; break; case 's': sort = 1; break; case 'v': verbose = 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 (argv[i]) { pat = FcNameParse ((FcChar8 *) argv[i]); while (argv[++i]) { if (!os) os = FcObjectSetCreate (); FcObjectSetAdd (os, argv[i]); } } else pat = FcPatternCreate (); if (!pat) return 1; FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); fs = FcFontSetCreate (); if (sort || all) { FcFontSet *font_patterns; int j; font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); if (!font_patterns || font_patterns->nfont == 0) { fputs("No fonts installed on the system\n", stderr); return 1; } for (j = 0; j < font_patterns->nfont; j++) { FcPattern *font_pattern; font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); if (font_pattern) FcFontSetAdd (fs, font_pattern); } FcFontSetSortDestroy (font_patterns); } else { FcPattern *match; match = FcFontMatch (0, pat, &result); if (match) FcFontSetAdd (fs, match); } FcPatternDestroy (pat); if (!format) { if (os) format = (const FcChar8 *) "%{=unparse}\n"; else format = (const FcChar8 *) "%{=fcmatch}\n"; } if (fs) { int j; for (j = 0; j < fs->nfont; j++) { FcPattern *font; font = FcPatternFilter (fs->fonts[j], os); if (verbose) { FcPatternPrint (font); } else { FcChar8 *s; s = FcPatternFormat (font, format); if (s) { printf ("%s", s); FcStrFree (s); } } FcPatternDestroy (font); } FcFontSetDestroy (fs); } if (os) FcObjectSetDestroy (os); FcFini (); return 0; }
int main (int argc, char **argv) { int index_set = 0; int set_index = 0; FcChar8 *format = NULL; int err = 0; int i; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:f:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:f:Vh")) != -1) #endif { switch (c) { case 'i': index_set = 1; set_index = atoi (optarg); 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); for (; i < argc; i++) { int index; int count = 0; index = set_index; do { FcPattern *pat; pat = FcFreeTypeQuery ((FcChar8 *) argv[i], index, NULL, &count); if (pat) { if (format) { FcChar8 *s; s = FcPatternFormat (pat, format); if (s) { printf ("%s", s); FcStrFree (s); } } else { FcPatternPrint (pat); } FcPatternDestroy (pat); } else { fprintf (stderr, "Can't query face %d of font file %s\n", index, argv[i]); err = 1; } index++; } while (!index_set && index < count); } FcFini (); return err; }
void JXFontManager::GetMonospaceFontNames ( JPtrArray<JString>* fontNames ) const { if (itsMonoFontNames != NULL) { fontNames->CopyObjects(*itsMonoFontNames, fontNames->GetCleanUpAction(), kJFalse); } else { (JXGetApplication())->DisplayBusyCursor(); fontNames->CleanOut(); fontNames->SetCompareFunction(JCompareStringsCaseInsensitive); fontNames->SetSortOrder(JOrderedSetT::kSortAscending); JPtrArray<JString> allFontNames(JPtrArrayT::kDeleteAll); allFontNames.SetCompareFunction(JCompareStringsCaseInsensitive); allFontNames.SetSortOrder(JOrderedSetT::kSortAscending); JString name; #if ENABLE_TRUE_TYPE FcFontSet* set = XftListFonts(*itsDisplay, itsDisplay->GetScreen(), FC_SPACING, FcTypeInteger, FC_MONO, NULL, FC_FAMILY, NULL); for (int i=0; i < set->nfont; i++) { FcChar8* s = FcNameUnparse(set->fonts[i]); name.Set((JCharacter*) s); // cout << "tt mono: " << name << endl; #if ONLY_STD_MONOSPACE if (!name.BeginsWith("Courier") && !name.BeginsWith("Consolas") && !name.Contains(" Mono") && name != "LucidaTypewriter") { FcStrFree(s); continue; } #endif if (IsUseless(name)) { FcStrFree(s); continue; } JBoolean isDuplicate; const JIndex index = allFontNames.GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { allFontNames.InsertAtIndex(index, name); JString* n = new JString(name); assert( n != NULL ); const JBoolean ok = fontNames->InsertSorted(n, kJFalse); assert( ok ); } FcStrFree(s); } FcFontSetDestroy(set); #else for (int j=0; j<kMonospaceFontPatternCount; j++) { int nameCount; char** nameList = XListFonts(*itsDisplay, kMonospaceFontPattern[j], INT_MAX, &nameCount); if (nameList == NULL) { return; } for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name name = JReadUntil(input, '-'); // font name if (name.IsEmpty() || name == "nil") { continue; } ConvertToPSFontName(&name); // cout << "std mono: " << name << endl; #if ONLY_STD_MONOSPACE if (name != "Clean" && name != "Fixed" && name != "Terminal" && name != "Courier" && name != "Lucidatypewriter" && name != "Profontwindows") { continue; } #endif if (IsUseless(name)) { continue; } JBoolean isDuplicate; const JIndex index = allFontNames.GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { allFontNames.InsertAtIndex(index, name); XFontStruct* xfont = XLoadQueryFont(*itsDisplay, nameList[i]); if (xfont != NULL) { if (xfont->min_bounds.width == xfont->max_bounds.width) { JString* n = new JString(name); assert( n != NULL ); const JBoolean ok = fontNames->InsertSorted(n, kJFalse); assert( ok ); } XFreeFont(*itsDisplay, xfont); } } } XFreeFontNames(nameList); } #endif // save names for next time itsMonoFontNames = new JDCCPtrArray<JString>(*fontNames, JPtrArrayT::kDeleteAll); assert( itsMonoFontNames != NULL ); } }
void JXFontManager::GetFontNames ( JPtrArray<JString>* fontNames ) const { if (itsAllFontNames != NULL) { fontNames->CopyObjects(*itsAllFontNames, fontNames->GetCleanUpAction(), kJFalse); } else { fontNames->CleanOut(); fontNames->SetCompareFunction(JCompareStringsCaseInsensitive); fontNames->SetSortOrder(JOrderedSetT::kSortAscending); JString name; #if ENABLE_TRUE_TYPE FcFontSet* set = XftListFonts(*itsDisplay, itsDisplay->GetScreen(), NULL, FC_FAMILY, NULL); for (int i=0; i < set->nfont; i++) { FcChar8* s = FcNameUnparse(set->fonts[i]); name.Set((JCharacter*) s); // cout << "tt font: " << name << endl; if (!IsPostscript(name) || IsUseless(name)) { FcStrFree(s); continue; } JBoolean isDuplicate; const JIndex index = fontNames->GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { fontNames->InsertAtIndex(index, name); } FcStrFree(s); } FcFontSetDestroy(set); #endif int nameCount; char** nameList = XListFonts(*itsDisplay, "-*-*-medium-r-normal-*-*-*-75-75-*-*-*-*", INT_MAX, &nameCount); if (nameList == NULL) { return; } for (int i=0; i<nameCount; i++) { const std::string s(nameList[i], strlen(nameList[i])); std::istringstream input(s); input.ignore(); // initial dash JIgnoreUntil(input, '-'); // foundry name name = JReadUntil(input, '-'); // font name if (name.IsEmpty() || name == "nil") { continue; } ConvertToPSFontName(&name); // cout << "std font: " << name << endl; if (!IsPostscript(name) || IsUseless(name)) { continue; } JBoolean isDuplicate; const JIndex index = fontNames->GetInsertionSortIndex(&name, &isDuplicate); if (!isDuplicate) { fontNames->InsertAtIndex(index, name); } } XFreeFontNames(nameList); // save names for next time itsAllFontNames = new JDCCPtrArray<JString>(*fontNames, JPtrArrayT::kDeleteAll); assert( itsAllFontNames != NULL ); } }
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; }
int main (int argc, char **argv) { unsigned int id = (unsigned int) -1; int brief = 0; FcFontSet *fs; FcChar8 *format = NULL; int err = 0; int i; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG while ((c = getopt_long (argc, argv, "i:bf:Vh", longopts, NULL)) != -1) #else while ((c = getopt (argc, argv, "i:bf:Vh")) != -1) #endif { switch (c) { case 'i': id = (unsigned int) strtol (optarg, NULL, 0); /* strtol() To handle -1. */ break; 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 (); #if defined(MIKTEX_WINDOWS) _setmode(_fileno(stdout), _O_BINARY); #endif for (; i < argc; i++) { if (!FcFreeTypeQueryAll ((FcChar8*) argv[i], id, NULL, NULL, fs)) { fprintf (stderr, _("Can't query face %u of font file %s\n"), id, argv[i]); err = 1; } } 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 err; }
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; FcChar8 *sysroot = FcConfigGetSysRoot (); /* * 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++) { const FcChar8 *subdir = FcCacheSubdir (cache, i); if (sysroot) { subdir = FcStrPlus (sysroot, subdir); if (!subdir) { fprintf (stderr, "malloc failure\n"); return ++ret; } } FcStrSetAdd (subdirs, subdir); if (sysroot) FcStrFree ((FcChar8 *) subdir); } 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; }
static FcValue FcConfigEvaluate (FcPattern *p, FcExpr *e) { FcValue v, vl, vr; FcResult r; FcMatrix *m; FcChar8 *str; switch (e->op) { case FcOpInteger: v.type = FcTypeInteger; v.u.i = e->u.ival; break; case FcOpDouble: v.type = FcTypeDouble; v.u.d = e->u.dval; break; case FcOpString: v.type = FcTypeString; v.u.s = e->u.sval; v = FcValueSave (v); break; case FcOpMatrix: v.type = FcTypeMatrix; v.u.m = e->u.mval; v = FcValueSave (v); break; case FcOpCharSet: v.type = FcTypeCharSet; v.u.c = e->u.cval; v = FcValueSave (v); break; case FcOpBool: v.type = FcTypeBool; v.u.b = e->u.bval; break; case FcOpField: r = FcPatternObjectGet (p, e->u.object, 0, &v); if (r != FcResultMatch) v.type = FcTypeVoid; v = FcValueSave (v); break; case FcOpConst: if (FcNameConstant (e->u.constant, &v.u.i)) v.type = FcTypeInteger; else v.type = FcTypeVoid; break; case FcOpQuest: vl = FcConfigEvaluate (p, e->u.tree.left); if (vl.type == FcTypeBool) { if (vl.u.b) v = FcConfigEvaluate (p, e->u.tree.right->u.tree.left); else v = FcConfigEvaluate (p, e->u.tree.right->u.tree.right); } else v.type = FcTypeVoid; FcValueDestroy (vl); break; case FcOpEqual: case FcOpNotEqual: case FcOpLess: case FcOpLessEqual: case FcOpMore: case FcOpMoreEqual: case FcOpContains: case FcOpNotContains: case FcOpListing: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); v.type = FcTypeBool; v.u.b = FcConfigCompareValue (&vl, e->op, &vr); FcValueDestroy (vl); FcValueDestroy (vr); break; case FcOpOr: case FcOpAnd: case FcOpPlus: case FcOpMinus: case FcOpTimes: case FcOpDivide: vl = FcConfigEvaluate (p, e->u.tree.left); vr = FcConfigEvaluate (p, e->u.tree.right); vl = FcConfigPromote (vl, vr); vr = FcConfigPromote (vr, vl); if (vl.type == vr.type) { switch (vl.type) { case FcTypeDouble: switch (e->op) { case FcOpPlus: v.type = FcTypeDouble; v.u.d = vl.u.d + vr.u.d; break; case FcOpMinus: v.type = FcTypeDouble; v.u.d = vl.u.d - vr.u.d; break; case FcOpTimes: v.type = FcTypeDouble; v.u.d = vl.u.d * vr.u.d; break; case FcOpDivide: v.type = FcTypeDouble; v.u.d = vl.u.d / vr.u.d; break; default: v.type = FcTypeVoid; break; } if (v.type == FcTypeDouble && v.u.d == (double) (int) v.u.d) { v.type = FcTypeInteger; v.u.i = (int) v.u.d; } break; case FcTypeBool: switch (e->op) { case FcOpOr: v.type = FcTypeBool; v.u.b = vl.u.b || vr.u.b; break; case FcOpAnd: v.type = FcTypeBool; v.u.b = vl.u.b && vr.u.b; break; default: v.type = FcTypeVoid; break; } break; case FcTypeString: switch (e->op) { case FcOpPlus: v.type = FcTypeString; str = FcStrPlus (vl.u.s, vr.u.s); v.u.s = FcStrStaticName (str); FcStrFree (str); if (!v.u.s) v.type = FcTypeVoid; break; default: v.type = FcTypeVoid; break; } break; case FcTypeMatrix: switch (e->op) { case FcOpTimes: v.type = FcTypeMatrix; m = malloc (sizeof (FcMatrix)); if (m) { FcMemAlloc (FC_MEM_MATRIX, sizeof (FcMatrix)); FcMatrixMultiply (m, vl.u.m, vr.u.m); v.u.m = m; } else { v.type = FcTypeVoid; } break; default: v.type = FcTypeVoid; break; } break; default: v.type = FcTypeVoid; break; } } else v.type = FcTypeVoid; FcValueDestroy (vl); FcValueDestroy (vr); break; case FcOpNot: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeBool: v.type = FcTypeBool; v.u.b = !vl.u.b; break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpFloor: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleFloor (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpCeil: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleCeil (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpRound: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleRound (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; case FcOpTrunc: vl = FcConfigEvaluate (p, e->u.tree.left); switch (vl.type) { case FcTypeInteger: v = vl; break; case FcTypeDouble: v.type = FcTypeInteger; v.u.i = FcDoubleTrunc (vl.u.d); break; default: v.type = FcTypeVoid; break; } FcValueDestroy (vl); break; default: v.type = FcTypeVoid; break; } return v; }