Add new API to find out a font from current search path
diff --git a/doc/fcpattern.fncs b/doc/fcpattern.fncs
index 928f0bc..912d43d 100644
--- a/doc/fcpattern.fncs
+++ b/doc/fcpattern.fncs
@@ -313,6 +313,16 @@
 <function>FcPatternGetRange</function> are available since 2.11.91.
 @@
 
+@RET@		FcResult
+@FUNC@		FcPatternFindFont
+@TYPE1@		const FcPattern *		@ARG1@		p
+@TYPE3@		FcChar8 **			@ARG3@		ret
+@PURPOSE@	Find a font corresponding to a filename in a pattern
+@DESC@
+Returns a filename in <parameter>p</parameter> to the font.
+@SINCE@		2.13.0
+@@
+
 @RET@		FcPattern *
 @FUNC@		FcPatternBuild
 @TYPE1@		FcPattern *			@ARG1@		pattern
diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h
index 6ceabc3..e7a0a59 100644
--- a/fontconfig/fontconfig.h
+++ b/fontconfig/fontconfig.h
@@ -931,6 +931,9 @@
 FcPublic FcResult
 FcPatternGetRange (const FcPattern *p, const char *object, int id, FcRange **r);
 
+FcPublic FcResult
+FcPatternFindFont (const FcPattern *p, FcChar8 **s);
+
 FcPublic FcPattern *
 FcPatternVaBuild (FcPattern *p, va_list va);
     
diff --git a/src/fccache.c b/src/fccache.c
index 9176019..6f7722d 100644
--- a/src/fccache.c
+++ b/src/fccache.c
@@ -221,6 +221,115 @@
     }
 }
 
+#define FC_ALIAS_HASH_SIZE 4099
+
+typedef struct _FcAliasBucket {
+    struct _FcAliasBucket *next;
+    FcChar8               *orig;
+    FcChar8               *alias;
+} FcAliasBucket;
+
+typedef struct _FcAliasHashTable {
+    FcAliasBucket *buckets[FC_ALIAS_HASH_SIZE];
+} FcAliasHashTable;
+
+static FcAliasHashTable alias_table;
+
+static FcBool
+FcCacheAliasAdd (FcAliasHashTable *table,
+		 const FcChar8    *orig,
+		 const FcChar8    *alias)
+{
+    FcAliasBucket **prev, *bucket;
+    FcChar32 hash = FcStrHashIgnoreCase (orig);
+
+    for (prev = &table->buckets[hash % FC_ALIAS_HASH_SIZE];
+	 (bucket = *prev); prev = &(bucket->next))
+    {
+	if (FcStrCmp (bucket->orig, orig) == 0)
+	    return FcTrue;
+    }
+    bucket = (FcAliasBucket *) malloc (sizeof (FcAliasBucket));
+    if (!bucket)
+	return FcFalse;
+    bucket->next = NULL;
+    bucket->orig = FcStrdup (orig);
+    bucket->alias = FcStrdup (alias);
+    if (!bucket->orig || !bucket->alias)
+    {
+	if (bucket->orig)
+	    FcStrFree (bucket->orig);
+	if (bucket->alias)
+	    FcStrFree (bucket->alias);
+	free (bucket);
+	return FcFalse;
+    }
+    *prev = bucket;
+
+    return FcTrue;
+}
+
+static FcBool
+FcCacheAliasRemove (FcAliasHashTable *table,
+		    const FcChar8    *orig)
+{
+    FcAliasBucket **prev, *bucket;
+    FcChar32 hash = FcStrHashIgnoreCase (orig);
+
+    for (prev = &table->buckets[hash % FC_ALIAS_HASH_SIZE];
+	 (bucket = *prev); )
+    {
+	if (FcStrCmp (bucket->orig, orig) == 0)
+	{
+	    *prev = bucket->next;
+	    FcStrFree (bucket->orig);
+	    FcStrFree (bucket->alias);
+	    free (bucket);
+
+	    return FcTrue;
+	}
+	else
+	    prev = &(bucket->next);
+    }
+    return FcFalse;
+}
+
+static FcBool
+FcCacheAliasFind (FcAliasHashTable *table,
+		  const FcChar8    *orig,
+		  const FcChar8    **ret)
+{
+    FcAliasBucket *bucket;
+    FcChar32 hash = FcStrHashIgnoreCase (orig);
+
+    for (bucket = table->buckets[hash % FC_ALIAS_HASH_SIZE]; bucket; bucket = bucket->next)
+    {
+	if (FcStrCmp (bucket->orig, orig) == 0)
+	{
+	    *ret = bucket->alias;
+	    return FcTrue;
+	}
+    }
+    return FcFalse;
+}
+
+static void
+FcDirCacheAddAliasPath (const FcChar8 *orig,
+			const FcChar8 *alias)
+{
+    FcCacheAliasAdd (&alias_table, orig, alias);
+}
+
+const FcChar8 *
+FcDirCacheFindAliasPath (const FcChar8 *dir)
+{
+    const FcChar8 *ret = NULL;
+
+    if (FcCacheAliasFind (&alias_table, dir, &ret))
+	return ret;
+    return NULL;
+}
+
 struct MD5Context {
         FcChar32 buf[4];
         FcChar32 bits[2];
@@ -300,8 +409,12 @@
 FcDirCacheBasenameUUID (const FcChar8 *dir, FcChar8 cache_base[CACHEBASE_LEN])
 {
     uuid_t uuid;
+    const FcChar8 *alias;
 
-    if (FcCacheUuidFind (&uuid_table, dir, uuid))
+    alias = FcDirCacheFindAliasPath (dir);
+    if (!alias)
+	alias = dir;
+    if (FcCacheUuidFind (&uuid_table, alias, uuid))
     {
 	uuid_unparse (uuid, (char *) cache_base);
 	strcat ((char *) cache_base, "-" FC_ARCHITECTURE FC_CACHE_SUFFIX);
@@ -728,7 +841,12 @@
     {
 	if (FcRefDec (&skip->ref) == 1)
 	{
+	    const FcChar8 *d = FcDirCacheFindAliasPath (FcCacheDir (skip->cache));
+
 	    FcCacheUuidRemove (&uuid_table, FcCacheDir (skip->cache));
+	    if (d)
+		FcCacheUuidRemove (&uuid_table, d);
+	    FcCacheAliasRemove (&alias_table, FcCacheDir (skip->cache));
 	    FcDirCacheDisposeUnlocked (skip->cache);
 	}
     }
@@ -988,12 +1106,17 @@
 FcDirCacheLoad (const FcChar8 *dir, FcConfig *config, FcChar8 **cache_file)
 {
     FcCache *cache = NULL;
+    const FcChar8 *d;
 
+    FcDirCacheReadUUID (dir);
     if (!FcDirCacheProcess (config, dir,
 			    FcDirCacheMapHelper,
 			    &cache, cache_file))
 	return NULL;
-    FcDirCacheReadUUID (FcCacheDir (cache));
+
+    d = FcCacheDir (cache);
+    if (FcStrCmp (dir, d))
+	FcDirCacheAddAliasPath (d, dir);
 
     return cache;
 }
diff --git a/src/fcint.h b/src/fcint.h
index d1a2383..4a0888b 100644
--- a/src/fcint.h
+++ b/src/fcint.h
@@ -591,6 +591,9 @@
 FcDirCacheCreateUUID (const FcChar8 *dir,
 		      FcBool         force);
 
+FcPrivate const FcChar8 *
+FcDirCacheFindAliasPath (const FcChar8 *dir);
+
 FcPrivate FcCache *
 FcDirCacheScan (const FcChar8 *dir, FcConfig *config);
 
diff --git a/src/fcpat.c b/src/fcpat.c
index dd1307d..707afc0 100644
--- a/src/fcpat.c
+++ b/src/fcpat.c
@@ -1105,6 +1105,36 @@
     return FcPatternObjectGetRange (p, FcObjectFromName (object), id, r);
 }
 
+FcResult
+FcPatternFindFont (const FcPattern *p, FcChar8 **s)
+{
+    FcChar8 *file;
+    FcResult ret = FcResultNoMatch;
+
+    if (FcPatternObjectGetString (p, FC_FILE_OBJECT, 0, &file) == FcResultMatch)
+    {
+	FcChar8 *dir = FcStrDirname (file);
+	const FcChar8 *alias;
+
+	if ((alias = FcDirCacheFindAliasPath (dir)))
+	{
+	    FcChar8 *font = FcStrBasename (file);
+
+	    if (s)
+		*s = FcStrBuildFilename (alias, font, NULL);
+	    FcStrFree (font);
+	}
+	else
+	{
+	    if (s)
+		*s = FcStrdup (file);
+	}
+	ret = FcResultMatch;
+	FcStrFree (dir);
+    }
+    return ret;
+}
+
 FcPattern *
 FcPatternDuplicate (const FcPattern *orig)
 {