Imported Upstream version 2.12.1
[platform/upstream/fontconfig.git] / src / fcdir.c
index 593382f..fd62a34 100644 (file)
@@ -23,6 +23,9 @@
  */
 
 #include "fcint.h"
+#include "fcftint.h"
+#include <ft2build.h>
+#include FT_FREETYPE_H
 #include <dirent.h>
 
 FcBool
@@ -65,13 +68,20 @@ FcFileScanFontConfig (FcFontSet             *set,
                      const FcChar8     *file,
                      FcConfig          *config)
 {
+    FT_Library ftLibrary;
+    FT_Face    face;
     FcPattern  *font;
     FcBool     ret = FcTrue;
+    int                num_faces = 0;
+    int                num_instances = 0;
+    int                face_num = 0;
+    int                instance_num = 0;
     int                id;
-    int                count = 0;
     const FcChar8 *sysroot = FcConfigGetSysRoot (config);
 
-    id = 0;
+    if (FT_Init_FreeType (&ftLibrary))
+       return FcFalse;
+
     do
     {
        font = 0;
@@ -83,14 +93,22 @@ FcFileScanFontConfig (FcFontSet             *set,
            printf ("\tScanning file %s...", file);
            fflush (stdout);
        }
-       font = FcFreeTypeQuery (file, id, blanks, &count);
+
+       id = ((instance_num << 16) + face_num);
+       if (FT_New_Face (ftLibrary, (char *) file, id, &face))
+           return FcFalse;
+       num_faces = face->num_faces;
+       num_instances = face->style_flags >> 16;
+       font = FcFreeTypeQueryFace (face, file, id, blanks);
+       FT_Done_Face (face);
+
        if (FcDebug () & FC_DBG_SCAN)
            printf ("done\n");
        /*
         * Get rid of sysroot here so that targeting scan rule may contains FC_FILE pattern
         * and they should usually expect without sysroot.
         */
-       if (sysroot)
+       if (font && sysroot)
        {
            size_t len = strlen ((const char *)sysroot);
            FcChar8 *f = NULL;
@@ -136,10 +154,20 @@ FcFileScanFontConfig (FcFontSet           *set,
                ret = FcFalse;
            }
        }
-       else if (font)
-           FcPatternDestroy (font);
-       id++;
-    } while (font && ret && id < count);
+       else
+           ret = FcFalse;
+
+       if (instance_num < num_instances)
+           instance_num++;
+       else
+       {
+           face_num++;
+           instance_num = 0;
+       }
+    } while (font && ret && face_num < num_faces);
+
+    FT_Done_FreeType (ftLibrary);
+
     return ret;
 }
 
@@ -205,8 +233,7 @@ FcDirScanConfig (FcFontSet  *set,
                 FcBlanks       *blanks,
                 const FcChar8  *dir,
                 FcBool         force, /* XXX unused */
-                FcConfig       *config,
-                FcBool         scanOnly)
+                FcConfig       *config)
 {
     DIR                        *d;
     struct dirent      *e;
@@ -222,7 +249,7 @@ FcDirScanConfig (FcFontSet  *set,
     if (!set && !dirs)
        return FcTrue;
 
-    if (!blanks && !scanOnly)
+    if (!blanks)
        blanks = FcConfigGetBlanks (config);
 
     /* freed below */
@@ -248,7 +275,7 @@ FcDirScanConfig (FcFontSet  *set,
        goto bail;
     }
 
-    files = FcStrSetCreate ();
+    files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64);
     if (!files)
     {
        ret = FcFalse;
@@ -275,17 +302,7 @@ FcDirScanConfig (FcFontSet *set,
      * Scan file files to build font patterns
      */
     for (i = 0; i < files->num; i++)
-    {
-       if (scanOnly)
-       {
-           if (FcFileIsDir (files->strs[i]))
-               FcFileScanConfig (NULL, dirs, NULL, files->strs[i], config);
-       }
-       else
-       {
-           FcFileScanConfig (set, dirs, blanks, files->strs[i], config);
-       }
-    }
+       FcFileScanConfig (set, dirs, blanks, files->strs[i], config);
 
 bail2:
     FcStrSetDestroy (files);
@@ -309,15 +326,7 @@ FcDirScan (FcFontSet           *set,
     if (cache || !force)
        return FcFalse;
 
-    return FcDirScanConfig (set, dirs, blanks, dir, force, FcConfigGetCurrent (), FcFalse);
-}
-
-FcBool
-FcDirScanOnly (FcStrSet                *dirs,
-              const FcChar8    *dir,
-              FcConfig         *config)
-{
-    return FcDirScanConfig (NULL, dirs, NULL, dir, FcTrue, config, FcTrue);
+    return FcDirScanConfig (set, dirs, blanks, dir, force, FcConfigGetCurrent ());
 }
 
 /*
@@ -332,6 +341,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
     struct stat                dir_stat;
     const FcChar8      *sysroot = FcConfigGetSysRoot (config);
     FcChar8            *d;
+    int                        fd = -1;
 
     if (sysroot)
        d = FcStrBuildFilename (sysroot, dir, NULL);
@@ -348,14 +358,15 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
     if (!set)
        goto bail;
 
-    dirs = FcStrSetCreate ();
+    dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
     if (!dirs)
        goto bail1;
 
+    fd = FcDirCacheLock (dir, config);
     /*
      * Scan the dir
      */
-    if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config, FcFalse))
+    if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config))
        goto bail2;
 
     /*
@@ -371,6 +382,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config)
     FcDirCacheWrite (cache, config);
 
  bail2:
+    FcDirCacheUnlock (fd);
     FcStrSetDestroy (dirs);
  bail1:
     FcFontSetDestroy (set);
@@ -389,6 +401,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
     FcStrSet *dirs;
     const FcChar8 *sysroot = FcConfigGetSysRoot (config);
     FcChar8 *d = NULL;
+    int fd = -1;
 
     cache = FcDirCacheLoad (dir, config, NULL);
     if (!cache)
@@ -400,14 +413,15 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
        d = FcStrdup (dir);
     if (FcStatChecksum (d, &dir_stat) < 0)
        goto bail;
-    dirs = FcStrSetCreate ();
+    dirs = FcStrSetCreateEx (FCSS_GROW_BY_64);
     if (!dirs)
        goto bail;
 
+    fd = FcDirCacheLock (dir, config);
     /*
      * Scan the dir
      */
-    if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config, FcFalse))
+    if (!FcDirScanConfig (NULL, dirs, NULL, d, FcTrue, config))
        goto bail1;
     /*
      * Rebuild the cache object
@@ -422,6 +436,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config)
     FcDirCacheWrite (new, config);
 
 bail1:
+    FcDirCacheUnlock (fd);
     FcStrSetDestroy (dirs);
 bail:
     if (d)