X-Git-Url: https://git.wh0rd.org/?a=blobdiff_plain;f=src%2Ffccfg.c;h=0f89b57a415f61cca22418e8cdcc52fd82c7bccd;hb=390c05e64a3716f6ea6fd81cf3ab63439051fbaa;hp=bcc3bd28d5525839c600b574beace725967648b9;hpb=2d3387fd720f33f80847ae6cbb83d94c9a52fde3;p=fontconfig.git diff --git a/src/fccfg.c b/src/fccfg.c index bcc3bd2..0f89b57 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -1,5 +1,5 @@ /* - * $RCSId: xc/lib/fontconfig/src/fccfg.c,v 1.23 2002/08/31 22:17:32 keithp Exp $ + * fontconfig/src/fccfg.c * * Copyright © 2000 Keith Packard * @@ -13,9 +13,9 @@ * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR @@ -85,14 +85,17 @@ FcConfigCreate (void) config->substPattern = 0; config->substFont = 0; + config->substScan = 0; config->maxObjects = 0; for (set = FcSetSystem; set <= FcSetApplication; set++) config->fonts[set] = 0; - config->caches = NULL; - config->rescanTime = time(0); config->rescanInterval = 30; + + config->expr_pool = NULL; + + config->ref = 1; return config; @@ -128,7 +131,7 @@ FcConfigNewestFile (FcStrSet *files) if (list) { while ((file = FcStrListNext (list))) - if (stat ((char *) file, &statb) == 0) + if (FcStat ((char *) file, &statb) == 0) if (!newest.set || statb.st_mtime - newest.time > 0) { newest.set = FcTrue; @@ -139,23 +142,10 @@ FcConfigNewestFile (FcStrSet *files) return newest; } -FcFileTime -FcConfigModifiedTime (FcConfig *config) -{ - if (!config) - { - FcFileTime v = { 0, FcFalse }; - config = FcConfigGetCurrent (); - if (!config) - return v; - } - return FcConfigNewestFile (config->configFiles); -} - FcBool FcConfigUptoDate (FcConfig *config) { - FcFileTime config_time, font_time; + FcFileTime config_time, config_dir_time, font_time; time_t now = time(0); if (!config) { @@ -164,11 +154,24 @@ FcConfigUptoDate (FcConfig *config) return FcFalse; } config_time = FcConfigNewestFile (config->configFiles); + config_dir_time = FcConfigNewestFile (config->configDirs); font_time = FcConfigNewestFile (config->fontDirs); if ((config_time.set && config_time.time - config->rescanTime > 0) || + (config_dir_time.set && (config_dir_time.time - config->rescanTime) > 0) || (font_time.set && (font_time.time - config->rescanTime) > 0)) { - return FcFalse; + /* We need to check for potential clock problems here (OLPC ticket #6046) */ + if ((config_time.set && (config_time.time - now) > 0) || + (config_dir_time.set && (config_dir_time.time - now) > 0) || + (font_time.set && (font_time.time - now) > 0)) + { + fprintf (stderr, + "Fontconfig warning: Directory/file mtime in the future. New fonts may not be detected\n"); + config->rescanTime = now; + return FcTrue; + } + else + return FcFalse; } config->rescanTime = now; return FcTrue; @@ -192,11 +195,49 @@ FcSubstDestroy (FcSubst *s) } } +FcExpr * +FcConfigAllocExpr (FcConfig *config) +{ + if (!config->expr_pool || config->expr_pool->next == config->expr_pool->end) + { + FcExprPage *new_page; + + new_page = malloc (sizeof (FcExprPage)); + if (!new_page) + return 0; + FcMemAlloc (FC_MEM_EXPR, sizeof (FcExprPage)); + + new_page->next_page = config->expr_pool; + new_page->next = new_page->exprs; + config->expr_pool = new_page; + } + + return config->expr_pool->next++; +} + +FcConfig * +FcConfigReference (FcConfig *config) +{ + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return 0; + } + + config->ref++; + + return config; +} + void FcConfigDestroy (FcConfig *config) { FcSetName set; - FcCacheList *cl, *cl_next; + FcExprPage *page; + + if (--config->ref > 0) + return; if (config == _fcConfig) _fcConfig = 0; @@ -215,15 +256,18 @@ FcConfigDestroy (FcConfig *config) FcSubstDestroy (config->substPattern); FcSubstDestroy (config->substFont); + FcSubstDestroy (config->substScan); for (set = FcSetSystem; set <= FcSetApplication; set++) if (config->fonts[set]) FcFontSetDestroy (config->fonts[set]); - for (cl = config->caches; cl; cl = cl_next) + page = config->expr_pool; + while (page) { - cl_next = cl->next; - FcDirCacheUnmap (cl->cache); - free (cl); + FcExprPage *next = page->next_page; + FcMemFree (FC_MEM_EXPR, sizeof (FcExprPage)); + free (page); + page = next; } free (config); @@ -231,92 +275,129 @@ FcConfigDestroy (FcConfig *config) } /* - * Scan the current list of directories in the configuration - * and build the set of available fonts. Update the - * per-user cache file to reflect the new configuration + * Add cache to configuration, adding fonts and directories */ FcBool -FcConfigBuildFonts (FcConfig *config) +FcConfigAddCache (FcConfig *config, FcCache *cache, + FcSetName set, FcStrSet *dirSet) { - FcFontSet *fonts, *cached_fonts; - FcStrList *list; - FcStrSet *oldDirs; - FcChar8 *dir; - - fonts = FcFontSetCreate (); - if (!fonts) - goto bail0; - - oldDirs = FcStrSetCreate (); - if (!oldDirs) - goto bail2; - - cached_fonts = FcCacheRead(config); - if (!cached_fonts) + FcFontSet *fs; + intptr_t *dirs; + int i; + + /* + * Add fonts + */ + fs = FcCacheSet (cache); + if (fs) { - list = FcConfigGetFontDirs (config); - if (!list) - goto bail3; + int nref = 0; - while ((dir = FcStrListNext (list))) + for (i = 0; i < fs->nfont; i++) { - if (FcDebug () & FC_DBG_FONTSET) - printf ("build scan dir %s\n", dir); - FcDirScanConfig (fonts, config->fontDirs, - config->blanks, dir, FcFalse, config); + FcPattern *font = FcFontSetFont (fs, i); + FcChar8 *font_file; + + /* + * Check to see if font is banned by filename + */ + if (FcPatternObjectGetString (font, FC_FILE_OBJECT, + 0, &font_file) == FcResultMatch && + !FcConfigAcceptFilename (config, font_file)) + { + continue; + } + + /* + * Check to see if font is banned by pattern + */ + if (!FcConfigAcceptFont (config, font)) + continue; + + nref++; + FcFontSetAdd (config->fonts[set], font); } - - FcStrListDone (list); + FcDirCacheReference (cache, nref); } - else - { - int i; - - for (i = 0; i < oldDirs->num; i++) - { - if (FcDebug () & FC_DBG_FONTSET) - printf ("scan dir %s\n", oldDirs->strs[i]); - FcDirScanConfig (fonts, config->fontDirs, - config->blanks, oldDirs->strs[i], - FcFalse, config); - } - for (i = 0; i < cached_fonts->nfont; i++) + /* + * Add directories + */ + dirs = FcCacheDirs (cache); + if (dirs) + { + for (i = 0; i < cache->dirs_count; i++) { - FcChar8 *cfn; - FcPattern *font = cached_fonts->fonts[i]; - FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &cfn); - - if (FcConfigAcceptFont (config, font) && - (cfn && FcConfigAcceptFilename (config, cfn))) - FcFontSetAdd (fonts, font); - - cached_fonts->fonts[i] = 0; /* prevent free in FcFontSetDestroy */ + FcChar8 *dir = FcOffsetToPtr (dirs, dirs[i], FcChar8); + if (FcConfigAcceptFilename (config, dir)) + FcStrSetAddFilename (dirSet, dir); } - cached_fonts->nfont = 0; - FcFontSetDestroy (cached_fonts); } + return FcTrue; +} + +static FcBool +FcConfigAddDirList (FcConfig *config, FcSetName set, FcStrSet *dirSet) +{ + FcStrList *dirlist; + FcChar8 *dir; + FcCache *cache; - if (FcDebug () & FC_DBG_FONTSET) - FcFontSetPrint (fonts); + 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); + } + FcStrListDone (dirlist); + return FcTrue; +} + +/* + * Scan the current list of directories in the configuration + * and build the set of available fonts. + */ - FcStrSetDestroy (oldDirs); +FcBool +FcConfigBuildFonts (FcConfig *config) +{ + FcFontSet *fonts; + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return FcFalse; + } + + fonts = FcFontSetCreate (); + if (!fonts) + return FcFalse; + FcConfigSetFonts (config, fonts, FcSetSystem); + if (!FcConfigAddDirList (config, FcSetSystem, config->fontDirs)) + return FcFalse; + if (FcDebug () & FC_DBG_FONTSET) + FcFontSetPrint (fonts); return FcTrue; -bail3: - FcStrSetDestroy (oldDirs); -bail2: - FcFontSetDestroy (fonts); -bail0: - return FcFalse; } FcBool FcConfigSetCurrent (FcConfig *config) { + if (config == _fcConfig) + return FcTrue; + if (!config->fonts) if (!FcConfigBuildFonts (config)) return FcFalse; @@ -457,19 +538,6 @@ FcConfigSetFonts (FcConfig *config, config->fonts[set] = fonts; } -FcBool -FcConfigAddCache (FcConfig *config, FcCache *cache) -{ - FcCacheList *cl = malloc (sizeof (FcCacheList)); - - if (!cl) - return FcFalse; - cl->cache = cache; - cl->next = config->caches; - config->caches = cl; - return FcTrue; -} - FcBlanks * FcConfigGetBlanks (FcConfig *config) { @@ -506,7 +574,7 @@ FcConfigAddBlank (FcConfig *config, } int -FcConfigGetRescanInverval (FcConfig *config) +FcConfigGetRescanInterval (FcConfig *config) { if (!config) { @@ -518,7 +586,7 @@ FcConfigGetRescanInverval (FcConfig *config) } FcBool -FcConfigSetRescanInverval (FcConfig *config, int rescanInterval) +FcConfigSetRescanInterval (FcConfig *config, int rescanInterval) { if (!config) { @@ -530,6 +598,22 @@ FcConfigSetRescanInverval (FcConfig *config, int rescanInterval) return FcTrue; } +/* + * A couple of typos escaped into the library + */ +int +FcConfigGetRescanInverval (FcConfig *config) +{ + return FcConfigGetRescanInterval (config); +} + +FcBool +FcConfigSetRescanInverval (FcConfig *config, int rescanInterval) +{ + return FcConfigSetRescanInterval (config, rescanInterval); +} + + FcBool FcConfigAddEdit (FcConfig *config, FcTest *test, @@ -540,14 +624,23 @@ FcConfigAddEdit (FcConfig *config, FcTest *t; int num; + switch (kind) { + case FcMatchPattern: + prev = &config->substPattern; + break; + case FcMatchFont: + prev = &config->substFont; + break; + case FcMatchScan: + prev = &config->substScan; + break; + default: + return FcFalse; + } subst = (FcSubst *) malloc (sizeof (FcSubst)); if (!subst) return FcFalse; FcMemAlloc (FC_MEM_SUBST, sizeof (FcSubst)); - if (kind == FcMatchPattern) - prev = &config->substPattern; - else - prev = &config->substFont; for (; *prev; prev = &(*prev)->next); *prev = subst; subst->next = 0; @@ -667,7 +760,7 @@ FcConfigCompareValue (const FcValue *left_o, ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) != 0; break; case FcOpNotContains: - ret = FcStrCmpIgnoreCase (left.u.s, right.u.s) == 0; + ret = FcStrStrIgnoreCase (left.u.s, right.u.s) == 0; break; default: break; @@ -791,7 +884,8 @@ FcConfigEvaluate (FcPattern *p, FcExpr *e) break; case FcOpString: v.type = FcTypeString; - v.u.s = FcStrStaticName(e->u.sval); + v.u.s = e->u.sval; + v = FcValueSave (v); break; case FcOpMatrix: v.type = FcTypeMatrix; @@ -1269,6 +1363,20 @@ FcConfigSubstituteWithPat (FcConfig *config, return FcFalse; } + switch (kind) { + case FcMatchPattern: + s = config->substPattern; + break; + case FcMatchFont: + s = config->substFont; + break; + case FcMatchScan: + s = config->substScan; + break; + default: + return FcFalse; + } + st = (FcSubState *) malloc (config->maxObjects * sizeof (FcSubState)); if (!st && config->maxObjects) return FcFalse; @@ -1279,10 +1387,6 @@ FcConfigSubstituteWithPat (FcConfig *config, printf ("FcConfigSubstitute "); FcPatternPrint (p); } - if (kind == FcMatchPattern) - s = config->substPattern; - else - s = config->substFont; for (; s; s = s->next) { /* @@ -1480,10 +1584,16 @@ FcConfigSubstitute (FcConfig *config, return FcConfigSubstituteWithPat (config, p, 0, kind); } -#if defined (_WIN32) && (defined (PIC) || defined (DLL_EXPORT)) +#if defined (_WIN32) + +# define WIN32_LEAN_AND_MEAN +# define WIN32_EXTRA_LEAN +# include static FcChar8 fontconfig_path[1000] = ""; +# if (defined (PIC) || defined (DLL_EXPORT)) + BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, @@ -1521,12 +1631,12 @@ DllMain (HINSTANCE hinstDLL, return TRUE; } +# endif /* !PIC */ + #undef FONTCONFIG_PATH #define FONTCONFIG_PATH fontconfig_path -#else /* !(_WIN32 && PIC) */ - -#endif /* !(_WIN32 && PIC) */ +#endif /* !_WIN32 */ #ifndef FONTCONFIG_FILE #define FONTCONFIG_FILE "fonts.conf" @@ -1611,6 +1721,17 @@ FcConfigGetPath (void) } } +#ifdef _WIN32 + if (fontconfig_path[0] == '\0') + { + char *p; + if(!GetModuleFileName(NULL, fontconfig_path, sizeof(fontconfig_path))) + goto bail1; + p = strrchr (fontconfig_path, '\\'); + if (p) *p = '\0'; + strcat (fontconfig_path, "\\fonts"); + } +#endif dir = (FcChar8 *) FONTCONFIG_PATH; path[i] = malloc (strlen ((char *) dir) + 1); if (!path[i]) @@ -1667,7 +1788,7 @@ FcChar8 * FcConfigFilename (const FcChar8 *url) { FcChar8 *file, *dir, **path, **p; - + if (!url || !*url) { url = (FcChar8 *) getenv ("FONTCONFIG_FILE"); @@ -1750,7 +1871,7 @@ FcConfigAppFontAddFile (FcConfig *config, FcConfigSetFonts (config, set, FcSetApplication); } - if (!FcFileScanConfig (set, subdirs, config->blanks, file, FcFalse, config)) + if (!FcFileScanConfig (set, subdirs, config->blanks, file, config)) { FcStrSetDestroy (subdirs); return FcFalse; @@ -1772,9 +1893,7 @@ FcConfigAppFontAddDir (FcConfig *config, const FcChar8 *dir) { FcFontSet *set; - FcStrSet *subdirs; - FcStrList *sublist; - FcChar8 *subdir; + FcStrSet *dirs; if (!config) { @@ -1782,8 +1901,9 @@ FcConfigAppFontAddDir (FcConfig *config, if (!config) return FcFalse; } - subdirs = FcStrSetCreate (); - if (!subdirs) + + dirs = FcStrSetCreate (); + if (!dirs) return FcFalse; set = FcConfigGetFonts (config, FcSetApplication); @@ -1792,26 +1912,20 @@ FcConfigAppFontAddDir (FcConfig *config, set = FcFontSetCreate (); if (!set) { - FcStrSetDestroy (subdirs); + FcStrSetDestroy (dirs); return FcFalse; } FcConfigSetFonts (config, set, FcSetApplication); } - if (!FcDirScanConfig (set, subdirs, config->blanks, dir, FcFalse, config)) + FcStrSetAddFilename (dirs, dir); + + if (!FcConfigAddDirList (config, FcSetApplication, dirs)) { - FcStrSetDestroy (subdirs); + FcStrSetDestroy (dirs); return FcFalse; } - if ((sublist = FcStrListCreate (subdirs))) - { - while ((subdir = FcStrListNext (sublist))) - { - FcConfigAppFontAddDir (config, subdir); - } - FcStrListDone (sublist); - } - FcStrSetDestroy (subdirs); + FcStrSetDestroy (dirs); return FcTrue; } @@ -1937,3 +2051,6 @@ FcConfigAcceptFont (FcConfig *config, return FcFalse; return FcTrue; } +#define __fccfg__ +#include "fcaliastail.h" +#undef __fccfg__