diff -pruN fontconfig-2.13.0.orig/src/fccache.c fontconfig-2.13.0/src/fccache.c
--- fontconfig-2.13.0.orig/src/fccache.c 2017-12-18 21:45:13.000000000 +0900
+++ fontconfig-2.13.0/src/fccache.c 2018-06-08 18:39:33.079539192 +0900
@@ -51,13 +51,23 @@ FcDirCacheCreateUUID (FcChar8 *dir,
FcBool force,
FcConfig *config)
{
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ FcChar8 *target;
FcBool ret = FcTrue;
#ifndef _WIN32
FcChar8 *uuidname;
- uuidname = FcStrBuildFilename (dir, ".uuid", NULL);
+ if (sysroot)
+ target = FcStrBuildFilename (sysroot, dir, NULL);
+ else
+ target = FcStrdup (dir);
+ uuidname = FcStrBuildFilename (target, ".uuid", NULL);
+
if (!uuidname)
+ {
+ FcStrFree (target);
return FcFalse;
+ }
if (force || access ((const char *) uuidname, F_OK) < 0)
{
@@ -69,7 +79,7 @@ FcDirCacheCreateUUID (FcChar8 *dir,
struct stat statb;
struct timeval times[2];
- if (FcStat (dir, &statb) != 0)
+ if (FcStat (target, &statb) != 0)
{
ret = FcFalse;
goto bail1;
@@ -96,7 +106,7 @@ FcDirCacheCreateUUID (FcChar8 *dir,
hash_add = FcHashTableReplace;
else
hash_add = FcHashTableAdd;
- if (!hash_add (config->uuid_table, dir, uuid))
+ if (!hash_add (config->uuid_table, target, uuid))
{
ret = FcFalse;
goto bail3;
@@ -124,14 +134,15 @@ FcDirCacheCreateUUID (FcChar8 *dir,
times[0].tv_usec = 0;
times[1].tv_usec = 0;
#endif
- if (utimes ((const char *) dir, times) != 0)
+ if (utimes ((const char *) target, times) != 0)
{
- fprintf (stderr, "Unable to revert mtime: %s\n", dir);
+ fprintf (stderr, "Unable to revert mtime: %s\n", target);
}
}
}
- bail1:
+bail1:
FcStrFree (uuidname);
+ FcStrFree (target);
#endif
return ret;
@@ -144,10 +155,17 @@ FcDirCacheReadUUID (FcChar8 *dir,
{
void *u;
uuid_t uuid;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
+ FcChar8 *target;
- if (!FcHashTableFind (config->uuid_table, dir, &u))
+ if (sysroot)
+ target = FcStrBuildFilename (sysroot, dir, NULL);
+ else
+ target = FcStrdup (dir);
+
+ if (!FcHashTableFind (config->uuid_table, target, &u))
{
- FcChar8 *uuidname = FcStrBuildFilename (dir, ".uuid", NULL);
+ FcChar8 *uuidname = FcStrBuildFilename (target, ".uuid", NULL);
int fd;
if ((fd = FcOpen ((char *) uuidname, O_RDONLY)) >= 0)
@@ -162,7 +180,7 @@ FcDirCacheReadUUID (FcChar8 *dir,
{
if (FcDebug () & FC_DBG_CACHE)
printf ("FcDirCacheReadUUID %s -> %s\n", uuidname, suuid);
- FcHashTableAdd (config->uuid_table, dir, uuid);
+ FcHashTableAdd (config->uuid_table, target, uuid);
}
}
close (fd);
@@ -176,6 +194,7 @@ FcDirCacheReadUUID (FcChar8 *dir,
}
else
FcHashUuidFree (u);
+ FcStrFree (target);
}
#endif
@@ -259,19 +278,22 @@ static FcChar8 *
FcDirCacheBasenameUUID (const FcChar8 *dir, FcChar8 cache_base[CACHEBASE_LEN], FcConfig *config)
{
void *u;
- FcChar8 *alias;
+ FcChar8 *target;
+ const FcChar8 *sysroot = FcConfigGetSysRoot (config);
- if (!FcHashTableFind (config->alias_table, dir, (void **)&alias))
- alias = FcStrdup (dir);
- if (FcHashTableFind (config->uuid_table, alias, &u))
+ if (sysroot)
+ target = FcStrBuildFilename (sysroot, dir, NULL);
+ else
+ target = FcStrdup (dir);
+ if (FcHashTableFind (config->uuid_table, target, &u))
{
uuid_unparse (u, (char *) cache_base);
strcat ((char *) cache_base, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX);
FcHashUuidFree (u);
- FcStrFree (alias);
+ FcStrFree (target);
return cache_base;
}
- FcStrFree (alias);
+ FcStrFree (target);
return NULL;
}
#endif
@@ -417,6 +439,7 @@ struct _FcCacheSkip {
FcCache *cache;
FcRef ref;
intptr_t size;
+ void *allocated;
dev_t cache_dev;
ino_t cache_ino;
time_t cache_mtime;
@@ -542,6 +565,7 @@ FcCacheInsert (FcCache *cache, struct st
s->cache = cache;
s->size = cache->size;
+ s->allocated = NULL;
FcRefInit (&s->ref, 1);
if (cache_stat)
{
@@ -616,6 +640,7 @@ FcCacheRemoveUnlocked (FcCache *cache)
FcCacheSkip **update[FC_CACHE_MAX_LEVEL];
FcCacheSkip *s, **next;
int i;
+ void *allocated;
/*
* Find links along each chain
@@ -633,6 +658,15 @@ FcCacheRemoveUnlocked (FcCache *cache)
*update[i] = s->next[i];
while (fcCacheMaxLevel > 0 && fcCacheChains[fcCacheMaxLevel - 1] == NULL)
fcCacheMaxLevel--;
+
+ allocated = s->allocated;
+ while (allocated)
+ {
+ /* First element in allocated chunk is the free list */
+ next = *(void **)allocated;
+ free (allocated);
+ allocated = next;
+ }
free (s);
}
@@ -702,6 +736,30 @@ FcCacheObjectDereference (void *object)
unlock_cache ();
}
+void *
+FcCacheAllocate (FcCache *cache, size_t len)
+{
+ FcCacheSkip *skip;
+ void *allocated = NULL;
+
+ lock_cache ();
+ skip = FcCacheFindByAddrUnlocked (cache);
+ if (skip)
+ {
+ void *chunk = malloc (sizeof (void *) + len);
+ if (chunk)
+ {
+ /* First element in allocated chunk is the free list */
+ *(void **)chunk = skip->allocated;
+ skip->allocated = chunk;
+ /* Return the rest */
+ allocated = ((FcChar8 *)chunk) + sizeof (void *);
+ }
+ }
+ unlock_cache ();
+ return allocated;
+}
+
void
FcCacheFini (void)
{
@@ -955,7 +1013,6 @@ FcCache *
FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file)
{
FcCache *cache = NULL;
- const FcChar8 *d;
#ifndef _WIN32
FcDirCacheReadUUID ((FcChar8 *) dir, config);
@@ -965,10 +1022,6 @@ FcDirCacheLoad (const FcChar8 *dir, FcCo
&cache, cache_file))
return NULL;
- d = FcCacheDir (cache);
- if (FcStrCmp (dir, d))
- FcHashTableAdd (config->alias_table, (FcChar8 *) d, (FcChar8 *) dir);
-
return cache;
}
diff -pruN fontconfig-2.13.0.orig/src/fccfg.c fontconfig-2.13.0/src/fccfg.c
--- fontconfig-2.13.0.orig/src/fccfg.c 2018-06-08 18:34:36.546946321 +0900
+++ fontconfig-2.13.0/src/fccfg.c 2018-06-08 18:39:33.079539192 +0900
@@ -144,12 +144,6 @@ FcConfigCreate (void)
FcHashUuidCopy,
(FcDestroyFunc) FcStrFree,
FcHashUuidFree);
- config->alias_table = FcHashTableCreate ((FcHashFunc) FcStrHashIgnoreCase,
- (FcCompareFunc) FcStrCmp,
- FcHashStrCopy,
- FcHashStrCopy,
- (FcDestroyFunc) FcStrFree,
- (FcDestroyFunc) FcStrFree);
FcRefInit (&config->ref, 1);
@@ -313,7 +307,6 @@ FcConfigDestroy (FcConfig *config)
FcStrFree (config->sysRoot);
FcHashTableDestroy (config->uuid_table);
- FcHashTableDestroy (config->alias_table);
free (config);
}
@@ -324,11 +317,15 @@ FcConfigDestroy (FcConfig *config)
FcBool
FcConfigAddCache (FcConfig *config, FcCache *cache,
- FcSetName set, FcStrSet *dirSet)
+ FcSetName set, FcStrSet *dirSet, FcChar8 *forDir)
{
FcFontSet *fs;
intptr_t *dirs;
int i;
+ FcBool relocated = FcFalse;
+
+ if (strcmp ((char *)FcCacheDir(cache), (char *)forDir) != 0)
+ relocated = FcTrue;
/*
* Add fonts
@@ -342,23 +339,43 @@ FcConfigAddCache (FcConfig *config, FcCa
{
FcPattern *font = FcFontSetFont (fs, i);
FcChar8 *font_file;
+ FcChar8 *relocated_font_file = NULL;
- /*
- * Check to see if font is banned by filename
- */
if (FcPatternObjectGetString (font, FC_FILE_OBJECT,
- 0, &font_file) == FcResultMatch &&
- !FcConfigAcceptFilename (config, font_file))
+ 0, &font_file) == FcResultMatch)
{
- continue;
+ if (relocated)
+ {
+ FcChar8 *slash = FcStrLastSlash (font_file);
+ relocated_font_file = FcStrBuildFilename (forDir, slash + 1, NULL);
+ font_file = relocated_font_file;
+ }
+
+ /*
+ * Check to see if font is banned by filename
+ */
+ if (!FcConfigAcceptFilename (config, font_file))
+ {
+ free (relocated_font_file);
+ continue;
+ }
}
-
+
/*
* Check to see if font is banned by pattern
*/
if (!FcConfigAcceptFont (config, font))
+ {
+ free (relocated_font_file);
continue;
-
+ }
+
+ if (relocated_font_file)
+ {
+ font = FcPatternCacheRewriteFile (font, cache, relocated_font_file);
+ free (relocated_font_file);
+ }
+
if (FcFontSetAdd (config->fonts[set], font))
nref++;
}
@@ -374,18 +391,14 @@ FcConfigAddCache (FcConfig *config, FcCa
for (i = 0; i < cache->dirs_count; i++)
{
const FcChar8 *dir = FcCacheSubdir (cache, i);
- FcChar8 *alias;
- FcChar8 *d = FcStrDirname (dir);
FcChar8 *s = NULL;
- if (FcHashTableFind (config->alias_table, d, (void **)&alias))
+ if (relocated)
{
FcChar8 *base = FcStrBasename (dir);
- dir = s = FcStrBuildFilename (alias, base, NULL);
- FcStrFree (alias);
+ dir = s = FcStrBuildFilename (forDir, base, NULL);
FcStrFree (base);
}
- FcStrFree (d);
if (FcConfigAcceptFilename (config, dir))
FcStrSetAddFilename (dirSet, dir);
if (s)
@@ -413,7 +426,7 @@ FcConfigAddDirList (FcConfig *config, Fc
cache = FcDirCacheRead (dir, FcFalse, config);
if (!cache)
continue;
- FcConfigAddCache (config, cache, set, dirSet);
+ FcConfigAddCache (config, cache, set, dirSet, dir);
FcDirCacheUnload (cache);
}
FcStrListDone (dirlist);
diff -pruN fontconfig-2.13.0.orig/src/fcint.h fontconfig-2.13.0/src/fcint.h
--- fontconfig-2.13.0.orig/src/fcint.h 2018-02-04 19:20:56.000000000 +0900
+++ fontconfig-2.13.0/src/fcint.h 2018-06-08 18:39:33.080539208 +0900
@@ -566,7 +566,6 @@ struct _FcConfig {
FcStrSet *availConfigFiles; /* config files available */
FcPtrList *rulesetList; /* List of rulesets being installed */
FcHashTable *uuid_table; /* UUID table for cachedirs */
- FcHashTable *alias_table; /* alias table for cachedirs */
};
typedef struct _FcFileTime {
@@ -617,9 +616,13 @@ FcCacheObjectReference (void *object);
FcPrivate void
FcCacheObjectDereference (void *object);
+FcPrivate void *
+FcCacheAllocate (FcCache *cache, size_t len);
+
FcPrivate void
FcCacheFini (void);
+
FcPrivate void
FcDirCacheReference (FcCache *cache, int nref);
@@ -708,7 +711,7 @@ FcConfigModifiedTime (FcConfig *config);
FcPrivate FcBool
FcConfigAddCache (FcConfig *config, FcCache *cache,
- FcSetName set, FcStrSet *dirSet);
+ FcSetName set, FcStrSet *dirSet, FcChar8 *forDir);
FcPrivate FcRuleSet *
FcRuleSetCreate (const FcChar8 *name);
@@ -1150,6 +1153,9 @@ FcPatternAppend (FcPattern *p, FcPattern
FcPrivate int
FcPatternPosition (const FcPattern *p, const char *object);
+FcPrivate FcPattern *
+FcPatternCacheRewriteFile (const FcPattern *pat, FcCache *cache, const FcChar8 *relocated_font_file);
+
FcPrivate FcChar32
FcStringHash (const FcChar8 *s);
diff -pruN fontconfig-2.13.0.orig/src/fclist.c fontconfig-2.13.0/src/fclist.c
--- fontconfig-2.13.0.orig/src/fclist.c 2017-12-05 21:44:22.000000000 +0900
+++ fontconfig-2.13.0/src/fclist.c 2018-06-08 18:39:33.049538728 +0900
@@ -448,41 +448,6 @@ FcListAppend (FcListHashTable *table,
e = FcPatternObjectFindElt (font, FcObjectFromName (os->objects[o]));
if (e)
{
- if (FcRefIsConst (&font->ref) && !strcmp (os->objects[o], FC_FILE))
- {
- FcChar8 *dir, *alias;
- FcConfig *config = FcConfigGetCurrent (); /* FIXME: this may need to be exported as API? */
-
- for (v = FcPatternEltValues (e); v->value.type != FcTypeString; v = FcValueListNext (v));
- if (!v)
- goto bail2;
- dir = FcStrDirname (FcValueString (&v->value));
- if (FcHashTableFind (config->alias_table, dir, (void **) &alias))
- {
- FcChar8 *base = FcStrBasename (FcValueString (&v->value));
- FcChar8 *s = FcStrBuildFilename (alias, base, NULL);
- FcValue vv;
-
- FcStrFree (alias);
- FcStrFree (base);
- vv.type = FcTypeString;
- vv.u.s = s;
- if (!FcPatternAdd (bucket->pattern,
- os->objects[o],
- FcValueCanonicalize (&vv),
- FcTrue))
- {
- FcStrFree (s);
- FcStrFree (dir);
- goto bail2;
- }
- FcStrFree (s);
- FcStrFree (dir);
- goto bail3;
- }
- else
- FcStrFree (dir);
- }
for (v = FcPatternEltValues(e), idx = 0; v;
v = FcValueListNext(v), ++idx)
{
@@ -491,7 +456,6 @@ FcListAppend (FcListHashTable *table,
FcValueCanonicalize(&v->value), defidx != idx))
goto bail2;
}
- bail3:;
}
}
*prev = bucket;
diff -pruN fontconfig-2.13.0.orig/src/fcmatch.c fontconfig-2.13.0/src/fcmatch.c
--- fontconfig-2.13.0.orig/src/fcmatch.c 2017-12-23 14:06:22.000000000 +0900
+++ fontconfig-2.13.0/src/fcmatch.c 2018-06-08 18:39:33.050538743 +0900
@@ -682,43 +682,9 @@ FcFontRenderPrepare (FcConfig *confi
}
else
{
- if (FcRefIsConst (&font->ref) && fe->object == FC_FILE_OBJECT)
- {
- FcValueListPtr l = FcPatternEltValues (fe);
- FcChar8 *dir, *alias;
-
- while (l->value.type != FcTypeString)
- l = FcValueListNext (l);
- if (!l)
- goto bail0;
- dir = FcStrDirname (FcValueString (&l->value));
- if (!config)
- config = FcConfigGetCurrent ();
- if (config && FcHashTableFind (config->alias_table, dir, (void **) &alias))
- {
- FcChar8 *base = FcStrBasename (FcValueString (&l->value));
- FcChar8 *s = FcStrBuildFilename (alias, base, NULL);
- FcValue v;
-
- FcStrFree (alias);
- FcStrFree (base);
- v.type = FcTypeString;
- v.u.s = s;
- FcPatternObjectAddWithBinding (new, fe->object,
- FcValueCanonicalize (&v),
- l->binding,
- FcTrue);
- FcStrFree (s);
- FcStrFree (dir);
- goto bail0;
- }
- else
- FcStrFree (dir);
- }
FcPatternObjectListAdd (new, fe->object,
FcValueListDuplicate (FcPatternEltValues (fe)),
FcTrue);
- bail0:;
}
}
for (i = 0; i < pat->num; i++)
diff -pruN fontconfig-2.13.0.orig/src/fcpat.c fontconfig-2.13.0/src/fcpat.c
--- fontconfig-2.13.0.orig/src/fcpat.c 2017-12-20 19:20:15.000000000 +0900
+++ fontconfig-2.13.0/src/fcpat.c 2018-06-08 18:39:33.050538743 +0900
@@ -373,6 +373,71 @@ FcValueListHash (FcValueListPtr l)
return hash;
}
+static void *
+FcPatternGetCacheObject (FcPattern *p)
+{
+ /* We use a value to find the cache, instead of the FcPattern object
+ * because the pattern itself may be a cache allocation if we rewrote the path,
+ * so the p may not be in the cached region. */
+ return FcPatternEltValues(&FcPatternElts (p)[0]);
+}
+
+FcPattern *
+FcPatternCacheRewriteFile (const FcPattern *p,
+ FcCache *cache,
+ const FcChar8 *relocated_font_file)
+{
+ FcPatternElt *elts = FcPatternElts (p);
+ size_t i,j;
+ FcChar8 *data;
+ FcPattern *new_p;
+ FcPatternElt *new_elts;
+ FcValueList *new_value_list;
+ size_t new_path_len = strlen ((char *)relocated_font_file);
+ FcChar8 *new_path;
+
+ /* Allocate space for the patter, the PatternElt headers and
+ * the FC_FILE FcValueList and path that will be freed with the
+ * cache */
+ data = FcCacheAllocate (cache,
+ sizeof (FcPattern) +
+ p->num * sizeof (FcPatternElt) +
+ sizeof (FcValueList) +
+ new_path_len + 1);
+
+ new_p = (FcPattern *)data;
+ data += sizeof (FcPattern);
+ new_elts = (FcPatternElt *)(data);
+ data += p->num * sizeof (FcPatternElt);
+ new_value_list = (FcValueList *)data;
+ data += sizeof (FcValueList);
+ new_path = data;
+
+ *new_p = *p;
+ new_p->elts_offset = FcPtrToOffset (new_p, new_elts);
+
+ /* Copy all but the FILE values from the cache */
+ for (i = 0, j = 0; i < p->num; i++)
+ {
+ FcPatternElt *elt = &elts[i];
+ new_elts[j].object = elt->object;
+ if (elt->object != FC_FILE_OBJECT)
+ new_elts[j++].values = FcPatternEltValues(elt);
+ else
+ new_elts[j++].values = new_value_list;
+ }
+
+ new_value_list->next = NULL;
+ new_value_list->value.type = FcTypeString;
+ new_value_list->value.u.s = new_path;
+ new_value_list->binding = FcValueBindingWeak;
+
+ /* Add rewritten path at the end */
+ strcpy ((char *)new_path, (char *)relocated_font_file);
+
+ return new_p;
+}
+
void
FcPatternDestroy (FcPattern *p)
{
@@ -384,10 +449,10 @@ FcPatternDestroy (FcPattern *p)
if (FcRefIsConst (&p->ref))
{
- FcCacheObjectDereference (p);
+ FcCacheObjectDereference (FcPatternGetCacheObject(p));
return;
}
-
+
if (FcRefDec (&p->ref) != 1)
return;
@@ -1155,7 +1220,7 @@ FcPatternReference (FcPattern *p)
if (!FcRefIsConst (&p->ref))
FcRefInc (&p->ref);
else
- FcCacheObjectReference (p);
+ FcCacheObjectReference (FcPatternGetCacheObject(p));
}
FcPattern *
diff -pruN fontconfig-2.13.0.orig/test/run-test.sh fontconfig-2.13.0/test/run-test.sh
--- fontconfig-2.13.0.orig/test/run-test.sh 2017-12-18 21:25:18.000000000 +0900
+++ fontconfig-2.13.0/test/run-test.sh 2018-06-08 18:39:33.031538449 +0900
@@ -202,4 +202,29 @@ fi
rm -rf $TESTTMPDIR out1 out2 xxx bind-fonts.conf
fi
+dotest "sysroot option"
+prep
+mkdir -p $MyPWD/sysroot/$FONTDIR
+mkdir -p $MyPWD/sysroot/$CACHEDIR
+cp $FONT1 $MyPWD/sysroot/$FONTDIR
+cp $MyPWD/fonts.conf $MyPWD/sysroot/$MyPWD/fonts.conf
+$FCCACHE -y $MyPWD/sysroot
+stat $MyPWD/sysroot/$FONTDIR/.uuid
+if test $? != 0; then
+ echo "*** Test failed: $TEST"
+ exit 1
+fi
+
+dotest "creating uuid-based cache file on sysroot"
+uuid=`cat $MyPWD/sysroot/$FONTDIR/.uuid`
+ls $MyPWD/sysroot/$CACHEDIR/$uuid*
+if [ $? != 0 ]; then
+ echo "*** Test failed: $TEST"
+ echo "No cache for $uuid"
+ ls $MyPWD/sysroot/$CACHEDIR
+ exit 1
+fi
+
+rm -rf $MyPWD/sysroot
+
rm -rf $FONTDIR $CACHEFILE $CACHEDIR $FONTCONFIG_FILE out