Blame SOURCES/fontconfig-fix-flatpak.patch

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