diff --git a/src/fccache.c b/src/fccache.c index f2b09cb..b681a5e 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -590,7 +590,7 @@ FcCacheTimeValid (FcConfig *config, FcCache *cache, struct stat *dir_stat) static FcBool FcCacheDirsValid (FcConfig *config, FcCache *cache) { - FcStrSet *dirs = FcStrSetCreate (); + FcStrSet *dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); FcBool ret = FcFalse; const FcChar8 *sysroot = FcConfigGetSysRoot (config); FcChar8 *d; diff --git a/src/fccfg.c b/src/fccfg.c index 5f8f644..9f8ee7c 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -2205,7 +2205,7 @@ FcConfigAppFontAddFile (FcConfig *config, return FcFalse; } - subdirs = FcStrSetCreate (); + subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!subdirs) return FcFalse; @@ -2252,7 +2252,7 @@ FcConfigAppFontAddDir (FcConfig *config, return FcFalse; } - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) return FcFalse; diff --git a/src/fcdir.c b/src/fcdir.c index f4807dd..a046eae 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -248,7 +248,7 @@ FcDirScanConfig (FcFontSet *set, goto bail; } - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!files) { ret = FcFalse; @@ -349,7 +349,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) if (!set) goto bail; - dirs = FcStrSetCreate (); + dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!dirs) goto bail1; @@ -404,7 +404,7 @@ 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; diff --git a/src/fcint.h b/src/fcint.h index 8fa01d6..ee6cc99 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -339,11 +339,19 @@ struct _FcCharSet { FcCharLeaf)) #define FcCharSetNumbers(c) FcOffsetMember(c,numbers_offset,FcChar16) +#define FCSS_DEFAULT 0 /* default behavior */ +#define FCSS_ALLOW_DUPLICATES 1 /* allows for duplicate strings in the set */ +#define FCSS_GROW_BY_64 2 /* grows buffer by 64 elements instead of 1 */ + +#define FcStrSetHasControlBit(s,c) (s->control & c) +#define FcStrSetHasControlBits(s,c) ( (c) == (s->control & (c)) ) + struct _FcStrSet { FcRef ref; /* reference count */ int num; int size; FcChar8 **strs; + unsigned int control; /* control bits for set behavior */ }; struct _FcStrList { @@ -1113,6 +1121,9 @@ FcPrivate FcBool FcIsFsMtimeBroken (const FcChar8 *dir); /* fcstr.c */ +FcPrivate FcStrSet * +FcStrSetCreateEx (unsigned int control); + FcPrivate FcBool FcStrSetAddLangs (FcStrSet *strs, const char *languages); diff --git a/src/fcstr.c b/src/fcstr.c index 29a577d..b65492d 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -880,7 +880,7 @@ FcStrBuildFilename (const FcChar8 *path, if (!path) return NULL; - sset = FcStrSetCreate (); + sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); if (!sset) return NULL; @@ -1129,6 +1129,12 @@ FcStrCanonFilename (const FcChar8 *s) FcStrSet * FcStrSetCreate (void) +{ + return FcStrSetCreateEx (FCSS_DEFAULT); +} + +FcStrSet * +FcStrSetCreateEx (unsigned int control) { FcStrSet *set = malloc (sizeof (FcStrSet)); if (!set) @@ -1137,29 +1143,42 @@ FcStrSetCreate (void) set->num = 0; set->size = 0; set->strs = 0; + set->control = control; return set; } +static FcBool +_FcStrSetGrow (FcStrSet *set, int growElements) +{ + /* accommodate an additional NULL entry at the end of the array */ + FcChar8 **strs = malloc ((set->size + growElements + 1) * sizeof (FcChar8 *)); + if (!strs) + return FcFalse; + if (set->num) + memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); + if (set->strs) + free (set->strs); + set->size = set->size + growElements; + set->strs = strs; + return FcTrue; +} + static FcBool _FcStrSetAppend (FcStrSet *set, FcChar8 *s) { - if (FcStrSetMember (set, s)) + if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES)) { - FcStrFree (s); - return FcTrue; + if (FcStrSetMember (set, s)) + { + FcStrFree (s); + return FcTrue; + } } if (set->num == set->size) { - FcChar8 **strs = malloc ((set->size + 2) * sizeof (FcChar8 *)); - - if (!strs) - return FcFalse; - if (set->num) - memcpy (strs, set->strs, set->num * sizeof (FcChar8 *)); - if (set->strs) - free (set->strs); - set->size = set->size + 1; - set->strs = strs; + int growElements = FcStrSetHasControlBit (set, FCSS_GROW_BY_64) ? 64 : 1; + if (!_FcStrSetGrow(set, growElements)) + return FcFalse; } set->strs[set->num++] = s; set->strs[set->num] = 0; diff --git a/src/fcxml.c b/src/fcxml.c index 52a0668..cd8fff1 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -3158,7 +3158,7 @@ FcConfigParseAndLoadDir (FcConfig *config, strcat ((char *) file, "/"); base = file + strlen ((char *) file); - files = FcStrSetCreate (); + files = FcStrSetCreateEx (FCSS_GROW_BY_64); if (!files) { ret = FcFalse;