diff options
Diffstat (limited to 'fontconfig/src')
-rw-r--r-- | fontconfig/src/fccache.c | 99 | ||||
-rw-r--r-- | fontconfig/src/fccfg.c | 57 | ||||
-rw-r--r-- | fontconfig/src/fcinit.c | 30 | ||||
-rw-r--r-- | fontconfig/src/fcint.h | 15 | ||||
-rw-r--r-- | fontconfig/src/fclang.c | 4 | ||||
-rw-r--r-- | fontconfig/src/fcstr.c | 62 |
6 files changed, 223 insertions, 44 deletions
diff --git a/fontconfig/src/fccache.c b/fontconfig/src/fccache.c index 36111bd89..fab2c1f2c 100644 --- a/fontconfig/src/fccache.c +++ b/fontconfig/src/fccache.c @@ -124,6 +124,7 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) FcChar8 cache_base[CACHEBASE_LEN]; FcStrList *list; FcChar8 *cache_dir; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcDirCacheBasename (dir, cache_base); @@ -133,7 +134,10 @@ FcDirCacheUnlink (const FcChar8 *dir, FcConfig *config) while ((cache_dir = FcStrListNext (list))) { - cache_hashed = FcStrPlus (cache_dir, cache_base); + 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); @@ -197,7 +201,13 @@ FcDirCacheProcess (FcConfig *config, const FcChar8 *dir, while ((cache_dir = FcStrListNext (list))) { - FcChar8 *cache_hashed = FcStrPlus (cache_dir, cache_base); + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + 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); @@ -859,11 +869,12 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) FcAtomic *atomic; FcStrList *list; FcChar8 *cache_dir = NULL; - FcChar8 *test_dir; + FcChar8 *test_dir, *d = NULL; FcCacheSkip *skip; struct stat cache_stat; unsigned int magic; int written; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); /* * Write it to the first directory in the list which is writable @@ -872,10 +883,18 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) list = FcStrListCreate (config->cacheDirs); if (!list) return FcFalse; - while ((test_dir = FcStrListNext (list))) { - if (access ((char *) test_dir, W_OK) == 0) + while ((test_dir = FcStrListNext (list))) + { + if (d) + FcStrFree (d); + if (sysroot) + d = FcStrBuildFilename (sysroot, test_dir, NULL); + else + d = FcStrCopyFilename (test_dir); + + if (access ((char *) d, W_OK) == 0) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); break; } else @@ -883,35 +902,38 @@ FcDirCacheWrite (FcCache *cache, FcConfig *config) /* * If the directory doesn't exist, try to create it */ - if (access ((char *) test_dir, F_OK) == -1) { - if (FcMakeDirectory (test_dir)) + if (access ((char *) d, F_OK) == -1) { + if (FcMakeDirectory (d)) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); /* Create CACHEDIR.TAG */ - FcDirCacheCreateTagFile (cache_dir); + FcDirCacheCreateTagFile (d); break; } } /* * Otherwise, try making it writable */ - else if (chmod ((char *) test_dir, 0755) == 0) + else if (chmod ((char *) d, 0755) == 0) { - cache_dir = test_dir; + cache_dir = FcStrCopyFilename (d); /* Try to create CACHEDIR.TAG too */ - FcDirCacheCreateTagFile (cache_dir); + FcDirCacheCreateTagFile (d); break; } } } + if (d) + FcStrFree (d); FcStrListDone (list); if (!cache_dir) return FcFalse; FcDirCacheBasename (dir, cache_base); - cache_hashed = FcStrPlus (cache_dir, cache_base); + cache_hashed = FcStrBuildFilename (cache_dir, cache_base, NULL); if (!cache_hashed) return FcFalse; + FcStrFree (cache_dir); if (FcDebug () & FC_DBG_CACHE) printf ("FcDirCacheWriteDir dir \"%s\" file \"%s\"\n", @@ -989,31 +1011,37 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) { DIR *d; struct dirent *ent; - FcChar8 *dir_base; + FcChar8 *dir; FcBool ret = FcTrue; FcBool remove; FcCache *cache; struct stat target_stat; + const FcChar8 *sysroot; - dir_base = FcStrPlus (cache_dir, (FcChar8 *) FC_DIR_SEPARATOR_S); - if (!dir_base) + /* FIXME: this API needs to support non-current FcConfig */ + sysroot = FcConfigGetSysRoot (NULL); + if (sysroot) + dir = FcStrBuildFilename (sysroot, cache_dir, NULL); + else + dir = FcStrCopyFilename (cache_dir); + if (!dir) { fprintf (stderr, "Fontconfig error: %s: out of memory\n", cache_dir); return FcFalse; } - if (access ((char *) cache_dir, W_OK) != 0) + if (access ((char *) dir, W_OK) != 0) { if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: not cleaning %s cache directory\n", cache_dir, - access ((char *) cache_dir, F_OK) == 0 ? "unwritable" : "non-existent"); + printf ("%s: not cleaning %s cache directory\n", dir, + access ((char *) dir, F_OK) == 0 ? "unwritable" : "non-existent"); goto bail0; } if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: cleaning cache directory\n", cache_dir); - d = opendir ((char *) cache_dir); + printf ("%s: cleaning cache directory\n", dir); + d = opendir ((char *) dir); if (!d) { - perror ((char *) cache_dir); + perror ((char *) dir); ret = FcFalse; goto bail0; } @@ -1030,10 +1058,10 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) strcmp(ent->d_name + 32, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX)) continue; - file_name = FcStrPlus (dir_base, (FcChar8 *) ent->d_name); + file_name = FcStrBuildFilename (dir, (FcChar8 *)ent->d_name, NULL); if (!file_name) { - fprintf (stderr, "Fontconfig error: %s: allocation failure\n", cache_dir); + fprintf (stderr, "Fontconfig error: %s: allocation failure\n", dir); ret = FcFalse; break; } @@ -1042,7 +1070,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) if (!cache) { if (verbose || FcDebug () & FC_DBG_CACHE) - printf ("%s: invalid cache file: %s\n", cache_dir, ent->d_name); + printf ("%s: invalid cache file: %s\n", dir, ent->d_name); remove = FcTrue; } else @@ -1052,7 +1080,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) { if (verbose || FcDebug () & FC_DBG_CACHE) printf ("%s: %s: missing directory: %s \n", - cache_dir, ent->d_name, target_dir); + dir, ent->d_name, target_dir); remove = FcTrue; } FcDirCacheUnload (cache); @@ -1070,7 +1098,7 @@ FcDirCacheClean (const FcChar8 *cache_dir, FcBool verbose) closedir (d); bail0: - FcStrFree (dir_base); + FcStrFree (dir); return ret; } @@ -1394,7 +1422,7 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) if (access ((char *) cache_dir, W_OK) == 0) { /* Create CACHEDIR.TAG */ - cache_tag = FcStrPlus (cache_dir, (const FcChar8 *) FC_DIR_SEPARATOR_S "CACHEDIR.TAG"); + cache_tag = FcStrBuildFilename (cache_dir, "CACHEDIR.TAG", NULL); if (!cache_tag) return FcFalse; atomic = FcAtomicCreate ((FcChar8 *)cache_tag); @@ -1438,8 +1466,9 @@ FcDirCacheCreateTagFile (const FcChar8 *cache_dir) void FcCacheCreateTagFile (const FcConfig *config) { - FcChar8 *cache_dir = NULL; + FcChar8 *cache_dir = NULL, *d = NULL; FcStrList *list; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); list = FcConfigGetCacheDirs (config); if (!list) @@ -1447,9 +1476,17 @@ FcCacheCreateTagFile (const FcConfig *config) while ((cache_dir = FcStrListNext (list))) { - if (FcDirCacheCreateTagFile (cache_dir)) + if (d) + FcStrFree (d); + if (sysroot) + d = FcStrBuildFilename (sysroot, cache_dir, NULL); + else + d = FcStrCopyFilename (cache_dir); + if (FcDirCacheCreateTagFile (d)) break; } + if (d) + FcStrFree (d); FcStrListDone (list); } diff --git a/fontconfig/src/fccfg.c b/fontconfig/src/fccfg.c index db878d5f4..b762376ae 100644 --- a/fontconfig/src/fccfg.c +++ b/fontconfig/src/fccfg.c @@ -123,6 +123,8 @@ FcConfigCreate (void) config->expr_pool = NULL; + config->sysRoot = NULL; + FcRefInit (&config->ref, 1); return config; @@ -292,6 +294,8 @@ FcConfigDestroy (FcConfig *config) free (page); page = next; } + if (config->sysRoot) + FcStrFree (config->sysRoot); free (config); } @@ -2309,6 +2313,59 @@ FcConfigAcceptFont (FcConfig *config, return FcFalse; return FcTrue; } + +const FcChar8 * +FcConfigGetSysRoot (const FcConfig *config) +{ + if (!config) + { + config = FcConfigGetCurrent (); + if (!config) + return NULL; + } + + return config->sysRoot; +} + +void +FcConfigSetSysRoot (FcConfig *config, + const FcChar8 *sysroot) +{ + FcChar8 *s; + FcBool init = FcFalse; + + if (!config) + { + /* We can't use FcConfigGetCurrent() here to ensure + * the sysroot is set prior to initialize FcConfig, + * to avoid loading caches from non-sysroot dirs. + * So postpone the initialization later. + */ + config = fc_atomic_ptr_get (&_fcConfig); + if (!config) + { + config = FcConfigCreate (); + if (!config) + return; + init = FcTrue; + } + } + + s = FcStrCopyFilename (sysroot); + if (!s) + return; + + if (config->sysRoot) + FcStrFree (config->sysRoot); + + config->sysRoot = s; + if (init) + { + config = FcInitLoadOwnConfigAndFonts (config); + FcConfigSetCurrent (config); + } +} + #define __fccfg__ #include "fcaliastail.h" #undef __fccfg__ diff --git a/fontconfig/src/fcinit.c b/fontconfig/src/fcinit.c index 2360764fc..b8d5d060c 100644 --- a/fontconfig/src/fcinit.c +++ b/fontconfig/src/fcinit.c @@ -65,14 +65,16 @@ FcGetVersion (void) * Load the configuration files */ FcConfig * -FcInitLoadConfig (void) +FcInitLoadOwnConfig (FcConfig *config) { - FcConfig *config; + if (!config) + { + config = FcConfigCreate (); + if (!config) + return NULL; + } FcInitDebug (); - config = FcConfigCreate (); - if (!config) - return NULL; if (!FcConfigParseAndLoad (config, 0, FcTrue)) { @@ -120,15 +122,19 @@ FcInitLoadConfig (void) return config; } +FcConfig * +FcInitLoadConfig (void) +{ + return FcInitLoadOwnConfig (NULL); +} + /* * Load the configuration files and scan for available fonts */ FcConfig * -FcInitLoadConfigAndFonts (void) +FcInitLoadOwnConfigAndFonts (FcConfig *config) { - FcConfig *config = FcInitLoadConfig (); - - FcInitDebug (); + config = FcInitLoadOwnConfig (config); if (!config) return 0; if (!FcConfigBuildFonts (config)) @@ -139,6 +145,12 @@ FcInitLoadConfigAndFonts (void) return config; } +FcConfig * +FcInitLoadConfigAndFonts (void) +{ + return FcInitLoadOwnConfigAndFonts (NULL); +} + /* * Initialize the default library configuration */ diff --git a/fontconfig/src/fcint.h b/fontconfig/src/fcint.h index 4eac6105a..d5a7217cc 100644 --- a/fontconfig/src/fcint.h +++ b/fontconfig/src/fcint.h @@ -501,7 +501,9 @@ struct _FcConfig { FcRef ref; /* reference count */ - FcExprPage *expr_pool; /* pool of FcExpr's */ + FcExprPage *expr_pool; /* pool of FcExpr's */ + + FcChar8 *sysRoot; /* override the system root directory */ }; typedef struct _FcFileTime { @@ -819,6 +821,13 @@ FcHashGetSHA256Digest (const FcChar8 *input_strings, FcPrivate FcChar8 * FcHashGetSHA256DigestFromFile (const FcChar8 *filename); +/* fcinit.c */ +FcPrivate FcConfig * +FcInitLoadOwnConfig (FcConfig *config); + +FcPrivate FcConfig * +FcInitLoadOwnConfigAndFonts (FcConfig *config); + /* fcxml.c */ FcPrivate void FcTestDestroy (FcTest *test); @@ -1073,6 +1082,10 @@ FcPrivate FcBool FcStrUsesHome (const FcChar8 *s); FcPrivate FcChar8 * +FcStrBuildFilename (const FcChar8 *path, + ...); + +FcPrivate FcChar8 * FcStrLastSlash (const FcChar8 *path); FcPrivate FcChar32 diff --git a/fontconfig/src/fclang.c b/fontconfig/src/fclang.c index 8e9b094b2..9f685f6fd 100644 --- a/fontconfig/src/fclang.c +++ b/fontconfig/src/fclang.c @@ -1027,9 +1027,11 @@ FcLangSetOperate(const FcLangSet *a, const FcChar8 *s)) { FcLangSet *langset = FcLangSetCopy (a); - FcStrList *sl = FcStrListCreate (FcLangSetGetLangs (b)); + FcStrSet *set = FcLangSetGetLangs (b); + FcStrList *sl = FcStrListCreate (set); FcChar8 *str; + FcStrSetDestroy (set); while ((str = FcStrListNext (sl))) { func (langset, str); diff --git a/fontconfig/src/fcstr.c b/fontconfig/src/fcstr.c index 414d6dd6b..4d11a4c65 100644 --- a/fontconfig/src/fcstr.c +++ b/fontconfig/src/fcstr.c @@ -30,6 +30,7 @@ #include <regex.h> #endif + /* Objects MT-safe for readonly access. */ FcChar8 * @@ -864,6 +865,64 @@ FcStrUsesHome (const FcChar8 *s) } FcChar8 * +FcStrBuildFilename (const FcChar8 *path, + ...) +{ + va_list ap; + FcStrSet *sset = FcStrSetCreate (); + FcStrList *list; + FcChar8 *s, *ret = NULL, *p; + size_t len = 0; + + if (!sset || !path) + return NULL; + + if (!FcStrSetAdd (sset, path)) + goto bail0; + + va_start (ap, path); + while (1) + { + s = (FcChar8 *)va_arg (ap, FcChar8 *); + if (!s) + break; + if (!FcStrSetAdd (sset, s)) + goto bail1; + } + list = FcStrListCreate (sset); + while ((s = FcStrListNext (list))) + { + len += strlen ((const char *)s) + 1; + } + list->n = 0; + ret = malloc (sizeof (FcChar8) * (len + 1)); + if (!ret) + goto bail2; + p = ret; + while ((s = FcStrListNext (list))) + { + if (p != ret) + { + p[0] = FC_DIR_SEPARATOR; + p++; + } + len = strlen ((const char *)s); + memcpy (p, s, len); + p += len; + } + *p = 0; + +bail2: + FcStrListDone (list); +bail1: + va_end (ap); +bail0: + FcStrSetDestroy (sset); + + return ret; +} + +FcChar8 * FcStrCopyFilename (const FcChar8 *s) { FcChar8 *new; @@ -1052,8 +1111,7 @@ FcStrCanonFilename (const FcChar8 *s) FcChar8 cwd[FC_MAX_FILE_LEN + 2]; if (getcwd ((char *) cwd, FC_MAX_FILE_LEN) == NULL) return NULL; - strcat ((char *) cwd, "/"); - full = FcStrPlus (cwd, s); + full = FcStrBuildFilename (cwd, s, NULL); file = FcStrCanonAbsoluteFilename (full); FcStrFree (full); return file; |