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