X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Ffcdir.c;h=fd62a342f812211a43d415c330c38ceeac80dccd;hb=00047ca256ef9a351039a0e900b8b784dc30e4c3;hp=2b476e8b94fd6dc1077a8c1b3cef1179533871bc;hpb=cee10818de2ea9e0b9644ce4bbd1683e1edd5319;p=platform%2Fupstream%2Ffontconfig.git diff --git a/src/fcdir.c b/src/fcdir.c index 2b476e8..fd62a34 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -23,6 +23,9 @@ */ #include "fcint.h" +#include "fcftint.h" +#include +#include FT_FREETYPE_H #include FcBool @@ -35,18 +38,50 @@ FcFileIsDir (const FcChar8 *file) return S_ISDIR(statb.st_mode); } +FcBool +FcFileIsLink (const FcChar8 *file) +{ +#if HAVE_LSTAT + struct stat statb; + + if (lstat ((const char *)file, &statb) != 0) + return FcFalse; + return S_ISLNK (statb.st_mode); +#else + return FcFalse; +#endif +} + +FcBool +FcFileIsFile (const FcChar8 *file) +{ + struct stat statb; + + if (FcStat (file, &statb) != 0) + return FcFalse; + return S_ISREG (statb.st_mode); +} + static FcBool FcFileScanFontConfig (FcFontSet *set, FcBlanks *blanks, 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); + + if (FT_Init_FreeType (&ftLibrary)) + return FcFalse; - id = 0; do { font = 0; @@ -58,9 +93,39 @@ 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 (font && sysroot) + { + size_t len = strlen ((const char *)sysroot); + FcChar8 *f = NULL; + + if (FcPatternObjectGetString (font, FC_FILE_OBJECT, 0, &f) == FcResultMatch && + strncmp ((const char *)f, (const char *)sysroot, len) == 0) + { + FcChar8 *s = FcStrdup (f); + FcPatternObjectDel (font, FC_FILE_OBJECT); + if (s[len] != '/') + len--; + else if (s[len+1] == '/') + len++; + FcPatternObjectAddString (font, FC_FILE_OBJECT, &s[len]); + FcStrFree (s); + } + } /* * Edit pattern with user-defined rules @@ -89,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; } @@ -104,18 +179,41 @@ FcFileScanConfig (FcFontSet *set, FcConfig *config) { if (FcFileIsDir (file)) - return FcStrSetAdd (dirs, file); + { + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + const FcChar8 *d = file; + size_t len; + + if (sysroot) + { + len = strlen ((const char *)sysroot); + if (strncmp ((const char *)file, (const char *)sysroot, len) == 0) + { + if (file[len] != '/') + len--; + else if (file[len+1] == '/') + len++; + d = &file[len]; + } + } + return FcStrSetAdd (dirs, d); + } else - return FcFileScanFontConfig (set, blanks, file, config); + { + if (set) + return FcFileScanFontConfig (set, blanks, file, config); + else + return FcTrue; + } } FcBool FcFileScan (FcFontSet *set, FcStrSet *dirs, - FcFileCache *cache, /* XXX unused */ + FcFileCache *cache FC_UNUSED, FcBlanks *blanks, const FcChar8 *file, - FcBool force) + FcBool force FC_UNUSED) { return FcFileScanConfig (set, dirs, blanks, file, FcConfigGetCurrent ()); } @@ -177,7 +275,7 @@ FcDirScanConfig (FcFontSet *set, goto bail; } - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!files) { ret = FcFalse; @@ -241,25 +339,34 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) FcFontSet *set; FcCache *cache = NULL; struct stat dir_stat; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *d; + int fd = -1; + + if (sysroot) + d = FcStrBuildFilename (sysroot, dir, NULL); + else + d = FcStrdup (dir); if (FcDebug () & FC_DBG_FONTSET) - printf ("cache scan dir %s\n", dir); + printf ("cache scan dir %s\n", d); - if (FcStatChecksum (dir, &dir_stat) < 0) + if (FcStatChecksum (d, &dir_stat) < 0) goto bail; set = FcFontSetCreate(); 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, dir, FcTrue, config)) + if (!FcDirScanConfig (set, dirs, NULL, d, FcTrue, config)) goto bail2; /* @@ -275,13 +382,69 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) FcDirCacheWrite (cache, config); bail2: + FcDirCacheUnlock (fd); FcStrSetDestroy (dirs); bail1: FcFontSetDestroy (set); bail: + FcStrFree (d); + return cache; } +FcCache * +FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) +{ + FcCache *cache; + FcCache *new = NULL; + struct stat dir_stat; + FcStrSet *dirs; + const FcChar8 *sysroot = FcConfigGetSysRoot (config); + FcChar8 *d = NULL; + int fd = -1; + + cache = FcDirCacheLoad (dir, config, NULL); + if (!cache) + goto bail; + + if (sysroot) + d = FcStrBuildFilename (sysroot, dir, NULL); + else + d = FcStrdup (dir); + if (FcStatChecksum (d, &dir_stat) < 0) + goto bail; + 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)) + goto bail1; + /* + * Rebuild the cache object + */ + new = FcDirCacheRebuild (cache, &dir_stat, dirs); + if (!new) + goto bail1; + FcDirCacheUnload (cache); + /* + * Write out the cache file, ignoring any troubles + */ + FcDirCacheWrite (new, config); + +bail1: + FcDirCacheUnlock (fd); + FcStrSetDestroy (dirs); +bail: + if (d) + FcStrFree (d); + + return new; +} + /* * Read (or construct) the cache for a directory */ @@ -302,7 +465,7 @@ FcDirCacheRead (const FcChar8 *dir, FcBool force, FcConfig *config) } FcBool -FcDirSave (FcFontSet *set, FcStrSet * dirs, const FcChar8 *dir) +FcDirSave (FcFontSet *set FC_UNUSED, FcStrSet * dirs FC_UNUSED, const FcChar8 *dir FC_UNUSED) { return FcFalse; /* XXX deprecated */ }