diff options
author | Akira TAGOH <akira@tagoh.org> | 2015-11-18 16:09:43 +0900 |
---|---|---|
committer | Akira TAGOH <akira@tagoh.org> | 2018-01-18 21:48:22 +0900 |
commit | f50a964a9f48fd2722648f39af23a2a6644e819b (patch) | |
tree | 960afb5f3a5bc848edb4ca1a28ec680d71d9d95b | |
parent | 73cc842d1dd866e4a6fda4aa422cb4a9c7a9832f (diff) |
initial work to support BCP47langtag-support
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | Tools.mk | 2 | ||||
-rw-r--r-- | configure.ac | 17 | ||||
-rw-r--r-- | fc-validate/fc-validate.c | 60 | ||||
-rw-r--r-- | fontconfig/fontconfig.h | 20 | ||||
-rw-r--r-- | src/Makefile.am | 17 | ||||
-rw-r--r-- | src/fccache.c | 12 | ||||
-rw-r--r-- | src/fccfg.c | 8 | ||||
-rw-r--r-- | src/fcdbg.c | 14 | ||||
-rw-r--r-- | src/fcdefault.c | 222 | ||||
-rw-r--r-- | src/fcdir.c | 12 | ||||
-rw-r--r-- | src/fcfreetype.c | 4 | ||||
-rw-r--r-- | src/fcinit.c | 4 | ||||
-rw-r--r-- | src/fcint.h | 191 | ||||
-rw-r--r-- | src/fclang.c | 29 | ||||
-rw-r--r-- | src/fcscript.c | 247 | ||||
-rw-r--r-- | src/fcstr.c | 168 | ||||
-rw-r--r-- | src/fcxml.c | 12 |
18 files changed, 850 insertions, 191 deletions
diff --git a/Makefile.am b/Makefile.am index cc3024e6..be38a658 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,7 +21,7 @@ # TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -SUBDIRS=fontconfig fc-case fc-lang src \ +SUBDIRS=fontconfig fc-case fc-lang fc-script src \ fc-cache fc-cat fc-conflist fc-list fc-match \ fc-pattern fc-query fc-scan fc-validate conf.d \ its po po-conf test @@ -43,7 +43,7 @@ AM_CPPFLAGS = \ $(WARN_CFLAGS) $(TOOL): $(TSRC) $(ALIAS_FILES) - $(AM_V_GEN) $(CC_FOR_BUILD) -o $(TOOL) $< $(AM_CPPFLAGS) + $(AM_V_GEN) $(CC_FOR_BUILD) $(CFLAGS) -o $(TOOL) $< $(AM_CPPFLAGS) $(LIBS) $(TARG): $(TMPL) $(TSRC) $(DEPS) $(AM_V_GEN) $(MAKE) $(TOOL) && \ diff --git a/configure.ac b/configure.ac index 51b64c47..8c9729a1 100644 --- a/configure.ac +++ b/configure.ac @@ -473,6 +473,22 @@ none|slight|medium|full) esac # +# Check liblangtag +# +AC_ARG_ENABLE(liblangtag, + [AC_HELP_STRING([--enable-liblangtag], + [Use liblangtag])]) + +if test "$enable_liblangtag" = "yes"; then + PKG_CHECK_MODULES([LIBLANGTAG], [liblangtag >= 0.5]) + PKGCONFIG_REQUIRES_PRIVATELY="$PKGCONFIG_REQUIRES_PRIVATELY liblangtag" + AC_DEFINE_UNQUOTED(ENABLE_LIBLANGTAG, 1, [Use liblangtag]) + + AC_SUBST(LIBLANGTAG_CFLAGS) + AC_SUBST(LIBLANGTAG_LIBS) +fi + +# # Set default font directory # @@ -779,6 +795,7 @@ fc-match/Makefile fc-pattern/Makefile fc-query/Makefile fc-scan/Makefile +fc-script/Makefile fc-validate/Makefile doc/Makefile doc/version.sgml diff --git a/fc-validate/fc-validate.c b/fc-validate/fc-validate.c index 2ceee202..76814085 100644 --- a/fc-validate/fc-validate.c +++ b/fc-validate/fc-validate.c @@ -63,6 +63,7 @@ static const struct option longopts[] = { {"index", 1, 0, 'i'}, {"lang", 1, 0, 'l'}, + {"script", 1, 0, 's'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, @@ -80,10 +81,10 @@ usage (char *program, int error) { FILE *file = error ? stderr : stdout; #if HAVE_GETOPT_LONG - fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] [--index index] [--lang LANG] [--verbose] [--version] [--help] font-file...\n"), + fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] [-s SCRIPT] [--index index] [--lang LANG] [--script SCRIPT] [--verbose] [--version] [--help] font-file...\n"), program); #else - fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] font-file...\n"), + fprintf (file, _("usage: %s [-Vhv] [-i index] [-l LANG] [-s SCRIPT] font-file...\n"), program); #endif fprintf (file, _("Validate font files and print result\n")); @@ -91,12 +92,14 @@ usage (char *program, int error) #if HAVE_GETOPT_LONG fprintf (file, _(" -i, --index INDEX display the INDEX face of each font file only\n")); fprintf (file, _(" -l, --lang=LANG set LANG instead of current locale\n")); + fprintf (file, _(" -s, --script=SCRIPT set SCRIPT instead of current locale\n")); fprintf (file, _(" -v, --verbose show more detailed information\n")); fprintf (file, _(" -V, --version display font config version and exit\n")); fprintf (file, _(" -h, --help display this help and exit\n")); #else fprintf (file, _(" -i INDEX (index) display the INDEX face of each font file only\n")); fprintf (file, _(" -l LANG (lang) set LANG instead of current locale\n")); + fprintf (file, _(" -s SCRIPT (script) set SCRIPT instead of current script\n")); fprintf (file, _(" -v (verbose) show more detailed information\n")); fprintf (file, _(" -V (version) display font config version and exit\n")); fprintf (file, _(" -h (help) display this help and exit\n")); @@ -110,7 +113,8 @@ main (int argc, char **argv) int index_set = 0; int set_index = 0; FcChar8 *lang = NULL; - const FcCharSet *fcs_lang = NULL; + FcChar8 *script = NULL; + const FcCharSet *fcs_lang = NULL, *fcs_script = NULL; int err = 0; int i; FT_Library ftlib; @@ -121,9 +125,9 @@ main (int argc, char **argv) setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG - while ((c = getopt_long (argc, argv, "i:l:mVhv", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "i:l:ms:Vhv", longopts, NULL)) != -1) #else - while ((c = getopt (argc, argv, "i:l:mVhv")) != -1) + while ((c = getopt (argc, argv, "i:l:ms:Vhv")) != -1) #endif { switch (c) { @@ -134,6 +138,9 @@ main (int argc, char **argv) case 'l': lang = (FcChar8 *) FcLangNormalize ((const FcChar8 *) optarg); break; + case 's': + script = (FcChar8 *) optarg; + break; case 'v': verbose = FcTrue; break; @@ -156,12 +163,16 @@ main (int argc, char **argv) if (i == argc) usage (argv[0], 1); - if (!lang) + if (!lang && !script) lang = FcLangNormalize ((const FcChar8 *) setlocale (LC_CTYPE, NULL)); if (lang) fcs_lang = FcLangGetCharSet (lang); + if (script) + fcs_script = FcScriptGetCharSet (script); + + printf("%p:%p\n", fcs_lang, fcs_script); if (FT_Init_FreeType (&ftlib)) { fprintf (stderr, _("Can't initalize FreeType library\n")); @@ -187,18 +198,40 @@ main (int argc, char **argv) } else { - FcChar32 count; + FcChar32 count, c; + FcBool eval; fcs = FcFreeTypeCharSet (face, NULL); - fcs_sub = FcCharSetSubtract (fcs_lang, fcs); + if (lang) + { + fcs_sub = FcCharSetSubtract (fcs_lang, fcs); + } + else + { + fcs_sub = FcCharSetSubtract (fcs_script, fcs); + } count = FcCharSetCount (fcs_sub); - if (count > 0) + if (lang) + eval = count > 0; + else + { + FcChar32 x; + + c = FcCharSetCount (fcs_script); + x = (c - count) * 100 / c; + eval = x < 60; + } + if (eval) { FcChar32 ucs4, pos, map[FC_CHARSET_MAP_SIZE]; - printf (_("%s:%d Missing %d glyph(s) to satisfy the coverage for %s language\n"), - argv[i], index, count, lang); + if (lang) + printf (_("%s:%d Missing %d glyph(s) to satisfy the coverage for %s language\n"), + argv[i], index, count, lang); + else + printf (_("%s:%d Missing %d glyph(s)[/%d] to satisfy the coverage for %s script\n", + argv[i], index, count, c, script); if (verbose) { @@ -227,7 +260,10 @@ main (int argc, char **argv) } else { - printf (_("%s:%d Satisfy the coverage for %s language\n"), argv[i], index, lang); + if (lang) + printf (_("%s:%d Satisfy the coverage for %s language\n"), argv[i], index, lang); + else + printf (_("%s:%d Satisfy the coverage for %s script\n"), argv[i], index, script); } FcCharSetDestroy (fcs); diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index b70ce9e8..00e4fe09 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -252,6 +252,8 @@ typedef struct _FcLangSet FcLangSet; typedef struct _FcRange FcRange; +typedef struct _FcScriptSet FcScriptSet; + typedef struct _FcValue { FcType type; union { @@ -321,6 +323,10 @@ typedef struct _FcGlobalCache FcFileCache; typedef struct _FcBlanks FcBlanks; +typedef struct _FcPtrList FcPtrList; + +typedef struct _FcPtrSet FcPtrSet; + typedef struct _FcStrList FcStrList; typedef struct _FcStrSet FcStrSet; @@ -560,6 +566,9 @@ FcPublic void FcFontSetPrint (const FcFontSet *s); /* fcdefault.c */ +FcPublic FcPtrSet * +FcGetDefaultLangtags (void); + FcPublic FcStrSet * FcGetDefaultLangs (void); @@ -975,6 +984,17 @@ FcWeightToOpenType (int fc_weight); FcPublic double FcWeightToOpenTypeDouble (double fc_weight); +/* fcscript.c */ + +FcPublic const FcCharSet * +FcScriptGetCharSet (const FcChar8 *script); + +FcPublic FcScriptSet * +FcScriptSetCreate (void); + +FcPublic void +FcScriptSetDestroy (FcScriptSet *ss); + /* fcstr.c */ FcPublic FcChar8 * diff --git a/src/Makefile.am b/src/Makefile.am index 80780b62..6dc3d235 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,6 +22,7 @@ # PERFORMANCE OF THIS SOFTWARE. EXTRA_DIST = +NULL = if OS_WIN32 @@ -73,8 +74,10 @@ endif AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(top_srcdir)/src \ + $(EXPAT_CFLAGS) \ $(FREETYPE_CFLAGS) \ $(ICONV_CFLAGS) \ + $(LIBLANGTAG_CFLAGS) \ $(LIBXML2_CFLAGS) \ $(EXPAT_CFLAGS) \ $(UUID_CFLAGS) \ @@ -92,6 +95,7 @@ ALIAS_FILES = fcalias.h fcaliastail.h fcftalias.h fcftaliastail.h BUILT_SOURCES = $(ALIAS_FILES) \ ../fc-case/fccase.h \ ../fc-lang/fclang.h \ + ../fc-script/fcscript.h \ stamp-fcstdint \ fcobjshash.h \ fcobjshash.gperf @@ -102,6 +106,8 @@ noinst_PROGRAMS = fcarch cd ../fc-case && $(MAKE) $(AM_MAKEFLAGS) fccase.h ../fc-lang/fclang.h: cd ../fc-lang && $(MAKE) $(AM_MAKEFLAGS) fclang.h +../fc-script/fcscript.h: + cd ../fc-script && $(MAKE) $(AM_MAKEFLAGS) fcscript.h fcobjshash.gperf: Makefile stamp-fcobjshash.gperf -@$(RM) stamp-fcobjshash.gperf @@ -152,7 +158,9 @@ libfontconfig_la_SOURCES = \ fcobjs.h \ fcobjshash.h \ fcpat.c \ + fcptr.c \ fcrange.c \ + fcscript.c \ fcserialize.c \ fcstat.c \ fcstr.c \ @@ -167,7 +175,14 @@ lib_LTLIBRARIES = libfontconfig.la libfontconfig_la_LDFLAGS = \ -version-info @LIBT_VERSION_INFO@ -no-undefined $(export_symbols) -libfontconfig_la_LIBADD = $(ICONV_LIBS) $(FREETYPE_LIBS) $(LIBXML2_LIBS) $(EXPAT_LIBS) $(UUID_LIBS) +libfontconfig_la_LIBADD = \ + $(EXPAT_LIBS) \ + $(FREETYPE_LIBS) \ + $(ICONV_LIBS) \ + $(LIBLANGTAG_LIBS) \ + $(LIBXML2_LIBS) \ + $(UUID_LIBS) \ + $(NULL) libfontconfig_la_DEPENDENCIES = $(fontconfig_def_dependency) diff --git a/src/fccache.c b/src/fccache.c index 7abb7507..7c320c58 100644 --- a/src/fccache.c +++ b/src/fccache.c @@ -1063,9 +1063,9 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt /* * Subdirs */ - FcSerializeAlloc (serialize, dirs, dirs->num * sizeof (FcChar8 *)); - for (i = 0; i < dirs->num; i++) - if (!FcStrSerializeAlloc (serialize, dirs->strs[i])) + FcSerializeAlloc (serialize, dirs, FcStrSetGetSize (dirs) * sizeof (FcChar8 *)); + for (i = 0; i < FcStrSetGetSize (dirs); i++) + if (!FcStrSerializeAlloc (serialize, FcStrSetIndex (dirs, i))) goto bail1; /* @@ -1106,10 +1106,10 @@ FcDirCacheBuild (FcFontSet *set, const FcChar8 *dir, struct stat *dir_stat, FcSt if (!dirs_serialize) goto bail2; cache->dirs = FcPtrToOffset (cache, dirs_serialize); - cache->dirs_count = dirs->num; - for (i = 0; i < dirs->num; i++) + cache->dirs_count = FcStrSetGetSize (dirs); + for (i = 0; i < FcStrSetGetSize (dirs); i++) { - FcChar8 *d_serialize = FcStrSerialize (serialize, dirs->strs[i]); + FcChar8 *d_serialize = FcStrSerialize (serialize, FcStrSetIndex (dirs, i)); if (!d_serialize) goto bail2; dirs_serialize[i] = FcPtrToOffset (dirs_serialize, d_serialize); diff --git a/src/fccfg.c b/src/fccfg.c index 2351ac23..0127d3f7 100644 --- a/src/fccfg.c +++ b/src/fccfg.c @@ -2258,7 +2258,7 @@ FcConfigAppFontAddFile (FcConfig *config, return FcFalse; } - subdirs = FcStrSetCreateEx (FCSS_GROW_BY_64); + subdirs = FcStrSetCreateEx (FC_SET_GROW_BY_64); if (!subdirs) return FcFalse; @@ -2305,7 +2305,7 @@ FcConfigAppFontAddDir (FcConfig *config, return FcFalse; } - dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); + dirs = FcStrSetCreateEx (FC_SET_GROW_BY_64); if (!dirs) return FcFalse; @@ -2365,8 +2365,8 @@ FcConfigGlobsMatch (const FcStrSet *globs, { int i; - for (i = 0; i < globs->num; i++) - if (FcStrGlobMatch (globs->strs[i], string)) + for (i = 0; i < FcStrSetGetSize (globs); i++) + if (FcStrGlobMatch (FcStrSetIndex (globs, i), string)) return FcTrue; return FcFalse; } diff --git a/src/fcdbg.c b/src/fcdbg.c index 2e16a312..fec8e436 100644 --- a/src/fcdbg.c +++ b/src/fcdbg.c @@ -151,6 +151,20 @@ FcLangSetPrint (const FcLangSet *ls) } void +FcScriptSetPrint (const FcScriptSet *ss) +{ + FcStrBuf buf; + FcChar8 init_buf[1024]; + + FcStrBufInit (&buf, init_buf, sizeof (init_buf)); + if (FcNameUnparseScriptSet (&buf, ss) && FcStrBufChar (&buf, '\0')) + printf ("%s", buf.buf); + else + printf ("scriptset (alloc error)"); + FcStrBufDestroy (&buf); +} + +void FcCharSetPrint (const FcCharSet *c) { int i, j; diff --git a/src/fcdefault.c b/src/fcdefault.c index 35973d79..85ef7226 100644 --- a/src/fcdefault.c +++ b/src/fcdefault.c @@ -25,6 +25,9 @@ #include "fcint.h" #include <limits.h> #include <string.h> +#ifdef ENABLE_LIBLANGTAG +#include <liblangtag/langtag.h> +#endif /* MT-safe */ @@ -44,7 +47,164 @@ static const struct { #define NUM_FC_BOOL_DEFAULTS (int) (sizeof FcBoolDefaults / sizeof FcBoolDefaults[0]) +#ifdef ENABLE_LIBLANGTAG +FcPtrSet *default_langtags; +lt_tag_t *default_langtag; + +static int +_tagcmp(const void *a, const void *b) +{ + return !lt_tag_compare (a, b); +} + +FcPtrSet * +FcGetDefaultLangtags (void) +{ + FcPtrSet *result; + +retry: + result = (FcPtrSet *) fc_atomic_ptr_get (&default_langtags); + if (!result) + { + char *langs; + static char *posix = "POSIX"; + const char *p, *next; + char *s = NULL; + size_t len; + lt_tag_t *tag = NULL; + lt_error_t *error = NULL; + + result = FcPtrSetCreate ((FcPtrSetDestroyFunc) lt_tag_unref, _tagcmp); + + langs = getenv ("FC_LANG"); + if (!langs || !langs[0]) + langs = getenv ("LC_ALL"); + if (!langs || !langs[0]) + langs = getenv ("LC_CTYPE"); + if (!langs || !langs[0]) + langs = getenv ("LANG"); + if (!langs || !langs[0]) + langs = posix; + + p = langs; + while ((next = strchr (p, ':'))) + { + len = next - p; + s = malloc (sizeof (char) * (len + 1)); + if (!s) + goto bail0; + memcpy (s, p, len); + s[len] = 0; + if (*s) + { + if (strchr (s, '@') || strchr (s, '_') || !strchr(s, '-')) + { + /* it may follows usual locale syntax */ + tag = lt_tag_convert_from_locale_string (s, &error); + if (!tag) + { + /* fallback to langtag */ + goto parse_tag; + } + } + else + { + parse_tag: + tag = lt_tag_new (); + if (!lt_tag_parse (tag, s, &error)) + { + lt_tag_unref (tag); + goto bail; + } + } + if (!FcPtrSetAdd (result, tag)) + goto bail; + } + free (s); + } + if (*p) + { + if (strchr (p, '@') || strchr (p, '_') || !strchr(p, '-')) + { + /* it may follows usual locale syntax */ + tag = lt_tag_convert_from_locale_string (p, &error); + if (!tag) + { + /* fallback to langtag */ + goto parse_tag2; + } + } + else + { + parse_tag2: + tag = lt_tag_new (); + if (!lt_tag_parse (tag, p, &error)) + { + lt_tag_unref (tag); + goto bail; + } + } + if (!FcPtrSetAdd (result, tag)) + goto bail; + } + bail: + if (lt_error_is_set (error, LT_ERR_ANY)) + { + lt_error_unref (error); + bail0: + FcPtrSetDestroy (result); + result = NULL; + } + else + { + FcPtrSetConst (result); + if (!fc_atomic_ptr_cmpexch (&default_langtags, NULL, result)) + { + FcPtrSetRefReset (result); + FcPtrSetDestroy (result); + goto retry; + } + } + } + + return result; +} + +lt_tag_t * +FcGetDefaultLangtag (void) +{ + lt_tag_t *tag; +retry: + tag = fc_atomic_ptr_get (&default_langtag); + if (!tag) + { + FcPtrSet *tags = FcGetDefaultLangtags (); + + tag = FcPtrSetIndex (tags, 0); + if (!fc_atomic_ptr_cmpexch (&default_langtag, NULL, tag)) { + goto retry; + } + } + + return tag; +} +#else +FcPtrSet * +FcGetDefaultLangtags (void) +{ + return NULL; +} + +lt_tag_t * +FcGetDefaultLangtag (void) +{ + return NULL; +} + +#endif + FcStrSet *default_langs; +static FcChar8 *default_lang; /* MT-safe */ FcStrSet * FcGetDefaultLangs (void) @@ -54,6 +214,28 @@ retry: result = (FcStrSet *) fc_atomic_ptr_get (&default_langs); if (!result) { +#ifdef ENABLE_LIBLANGTAG + FcPtrSet *tags = FcGetDefaultLangtags (); + FcPtrList *list = FcPtrListCreate (tags); + lt_tag_t *tag; + + result = FcStrSetCreate (); + + while ((tag = FcPtrListNext (list))) + { + lt_error_t *error = NULL; + char *lang = lt_tag_convert_to_locale (tag, &error); + + if (lt_error_is_set (error, LT_ERR_ANY)) + FcStrSetAdd (result, (const FcChar8 *) "en"); + else + if (!FcStrSetAddLangs (result, lang)) + FcStrSetAdd (result, (const FcChar8 *) "en"); + if (lang) + free (lang); + } + FcPtrListDone (list); +#else char *langs; result = FcStrSetCreate (); @@ -72,10 +254,11 @@ retry: } else FcStrSetAdd (result, (const FcChar8 *) "en"); +#endif - FcRefSetConst (&result->ref); + FcStrSetConst (result); if (!fc_atomic_ptr_cmpexch (&default_langs, NULL, result)) { - FcRefInit (&result->ref, 1); + FcStrSetRefReset (result); FcStrSetDestroy (result); goto retry; } @@ -84,8 +267,6 @@ retry: return result; } -static FcChar8 *default_lang; /* MT-safe */ - FcChar8 * FcGetDefaultLang (void) { @@ -94,8 +275,23 @@ retry: lang = fc_atomic_ptr_get (&default_lang); if (!lang) { +#ifdef ENABLE_LIBLANGTAG + lt_tag_t *tag = FcGetDefaultLangtag (); + + if (tag) + { + char *l = lt_tag_convert_to_locale (tag, NULL); + + if (l) + { + lang = FcLangNormalize ((const FcChar8 *) l); + free (l); + } + } +#else FcStrSet *langs = FcGetDefaultLangs (); - lang = FcStrdup (langs->strs[0]); + lang = FcStrdup (FcStrSetIndex (langs, 0)); +#endif if (!fc_atomic_ptr_cmpexch (&default_lang, NULL, lang)) { free (lang); @@ -214,19 +410,33 @@ retry: void FcDefaultFini (void) { +#ifdef ENABLE_LIBLANGTAG + lt_tag_t *lang; + FcPtrSet *langs; +#else FcChar8 *lang; FcStrSet *langs; +#endif FcChar8 *prgname; lang = fc_atomic_ptr_get (&default_lang); if (lang && fc_atomic_ptr_cmpexch (&default_lang, lang, NULL)) { +#ifdef ENABLE_LIBLANGTAG + lt_tag_unref (lang); +#else free (lang); +#endif } langs = fc_atomic_ptr_get (&default_langs); if (langs && fc_atomic_ptr_cmpexch (&default_langs, langs, NULL)) { - FcRefInit (&langs->ref, 1); +#ifdef ENABLE_LIBLANGTAG + FcPtrSetRefReset (langs); + FcPtrSetDestroy (langs); +#else + FcStrSetRefReset (langs); FcStrSetDestroy (langs); +#endif } prgname = fc_atomic_ptr_get (&default_prgname); diff --git a/src/fcdir.c b/src/fcdir.c index bfcdf956..c57b0af5 100644 --- a/src/fcdir.c +++ b/src/fcdir.c @@ -223,7 +223,7 @@ FcDirScanConfig (FcFontSet *set, goto bail; } - files = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); + files = FcStrSetCreateEx (FC_SET_ALLOW_DUPLICATES | FC_SET_GROW_BY_64); if (!files) { ret = FcFalse; @@ -244,13 +244,13 @@ FcDirScanConfig (FcFontSet *set, /* * Sort files to make things prettier */ - qsort(files->strs, files->num, sizeof(FcChar8 *), cmpstringp); + FcStrSetSort (files, cmpstringp); /* * Scan file files to build font patterns */ - for (i = 0; i < files->num; i++) - FcFileScanConfig (set, dirs, files->strs[i], config); + for (i = 0; i < FcStrSetGetSize (files); i++) + FcFileScanConfig (set, dirs, FcStrSetIndex (files, i), config); bail2: FcStrSetDestroy (files); @@ -308,7 +308,7 @@ FcDirCacheScan (const FcChar8 *dir, FcConfig *config) if (!set) goto bail; - dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); + dirs = FcStrSetCreateEx (FC_SET_GROW_BY_64); if (!dirs) goto bail1; @@ -369,7 +369,7 @@ FcDirCacheRescan (const FcChar8 *dir, FcConfig *config) d = FcStrdup (dir); if (FcStatChecksum (d, &dir_stat) < 0) goto bail; - dirs = FcStrSetCreateEx (FCSS_GROW_BY_64); + dirs = FcStrSetCreateEx (FC_SET_GROW_BY_64); if (!dirs) goto bail; diff --git a/src/fcfreetype.c b/src/fcfreetype.c index 49fb39f2..db888c89 100644 --- a/src/fcfreetype.c +++ b/src/fcfreetype.c @@ -1180,6 +1180,7 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, FcBool variable_size = FcFalse; FcCharSet *cs; FcLangSet *ls; + FcScriptSet *ss; #if 0 FcChar8 *family = 0; #endif @@ -1952,6 +1953,9 @@ FcFreeTypeQueryFaceInternal (const FT_Face face, if (!symbol) { + ss = FcFreeTypeScriptSet (cs); + if (!ss) + goto bail2; if (ls_share && *ls_share) ls = FcLangSetCopy (*ls_share); else diff --git a/src/fcinit.c b/src/fcinit.c index 8bb0fd4f..105bfa02 100644 --- a/src/fcinit.c +++ b/src/fcinit.c @@ -76,6 +76,7 @@ FcInitLoadOwnConfig (FcConfig *config) } FcInitDebug (); + FcLangInit (); if (!FcConfigParseAndLoad (config, 0, FcTrue)) { @@ -88,7 +89,7 @@ FcInitLoadOwnConfig (FcConfig *config) } (void) FcConfigParseOnly (config, (const FcChar8 *)FC_TEMPLATEDIR, FcFalse); - if (config->cacheDirs && config->cacheDirs->num == 0) + if (config->cacheDirs && FcStrSetGetSize (config->cacheDirs) == 0) { FcChar8 *prefix, *p; size_t plen; @@ -195,6 +196,7 @@ FcFini (void) FcDefaultFini (); FcObjectFini (); FcConfigPathFini (); + FcLangFini (); } /* diff --git a/src/fcint.h b/src/fcint.h index 537023fc..acb583bb 100644 --- a/src/fcint.h +++ b/src/fcint.h @@ -50,6 +50,9 @@ #include "fcdeprecate.h" #include "fcmutex.h" #include "fcatomic.h" +#ifdef ENABLE_LIBLANGTAG +#include <liblangtag/langtag.h> +#endif #ifndef FC_CONFIG_PATH #define FC_CONFIG_PATH "fonts.conf" @@ -82,18 +85,19 @@ extern pfnSHGetFolderPathA pSHGetFolderPathA; #define FC_UNUSED #endif -#define FC_DBG_MATCH 1 -#define FC_DBG_MATCHV 2 -#define FC_DBG_EDIT 4 -#define FC_DBG_FONTSET 8 -#define FC_DBG_CACHE 16 -#define FC_DBG_CACHEV 32 -#define FC_DBG_PARSE 64 -#define FC_DBG_SCAN 128 -#define FC_DBG_SCANV 256 -#define FC_DBG_CONFIG 1024 -#define FC_DBG_LANGSET 2048 -#define FC_DBG_MATCH2 4096 +#define FC_DBG_MATCH 1 +#define FC_DBG_MATCHV 2 +#define FC_DBG_EDIT 4 +#define FC_DBG_FONTSET 8 +#define FC_DBG_CACHE 16 +#define FC_DBG_CACHEV 32 +#define FC_DBG_PARSE 64 +#define FC_DBG_SCAN 128 +#define FC_DBG_SCANV 256 +#define FC_DBG_CONFIG 1024 +#define FC_DBG_LANGSET 2048 +#define FC_DBG_MATCH2 4096 +#define FC_DBG_SCRIPTSET 8192 #define _FC_ASSERT_STATIC1(_line, _cond) typedef int _static_assert_on_line_##_line##_failed[(_cond)?1:-1] FC_UNUSED #define _FC_ASSERT_STATIC0(_line, _cond) _FC_ASSERT_STATIC1 (_line, (_cond)) @@ -363,24 +367,37 @@ 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 FC_SET_DEFAULT 0 /* default behavior */ +#define FC_SET_ALLOW_DUPLICATES 1 /* allows for duplicate strings in the set */ +#define FC_SET_GROW_BY_64 2 /* grows buffer by 64 elements instead of 1 */ + +#define FcPtrSetHasControlBit(s,c) (s->control & c) +#define FcPtrSetHasControlBits(s,c) ( (c) == (s->control & (c)) ) + +typedef void (* FcPtrSetDestroyFunc) (void *p); +typedef int (* FcPtrSetCompareFunc) (const void *a, const void *b); + +struct _FcPtrSet { + FcRef ref; /* reference count */ + int num; + int size; + void **ptrs; + FcPtrSetDestroyFunc destroy_func; + FcPtrSetCompareFunc compare_func; + unsigned int control; /* control bits for set behavior */ +}; -#define FcStrSetHasControlBit(s,c) (s->control & c) -#define FcStrSetHasControlBits(s,c) ( (c) == (s->control & (c)) ) +struct _FcPtrList { + FcPtrSet *set; + int n; +}; struct _FcStrSet { - FcRef ref; /* reference count */ - int num; - int size; - FcChar8 **strs; - unsigned int control; /* control bits for set behavior */ + FcPtrSet ptrset; }; struct _FcStrList { - FcStrSet *set; - int n; + FcPtrList ptrlist; }; typedef struct _FcStrBuf { @@ -873,6 +890,13 @@ FcPrivate void FcInitDebug (void); /* fcdefault.c */ +#ifndef ENABLE_LIBLANGTAG +typedef lt_tag_t void +#endif + +FcPrivate lt_tag_t * +FcGetDefaultLangtag (void); + FcPrivate FcChar8 * FcGetDefaultLang (void); @@ -975,6 +999,13 @@ void FcRuleDestroy (FcRule *rule); /* fclang.c */ + +FcPrivate void +FcLangInit (void); + +FcPrivate void +FcLangFini (void); + FcPrivate FcLangSet * FcFreeTypeLangSet (const FcCharSet *charset, const FcChar8 *exclusiveLang); @@ -1169,6 +1200,87 @@ FcValueListSerializeAlloc (FcSerialize *serialize, const FcValueList *pat); FcPrivate FcValueList * FcValueListSerialize (FcSerialize *serialize, const FcValueList *pat); +/* fcptr.c */ + +FcPrivate FcPtrSet * +FcPtrSetInit (FcPtrSet *set, + unsigned int control, + FcPtrSetDestroyFunc destroy_func, + FcPtrSetCompareFunc compare_func); + +FcPrivate FcPtrSet * +FcPtrSetCreate (FcPtrSetDestroyFunc destroy_func, + FcPtrSetCompareFunc compare_func); + +FcPrivate FcPtrSet * +FcPtrSetCreateEx (unsigned int control, + FcPtrSetDestroyFunc destroy_func, + FcPtrSetCompareFunc compare_func); + +FcPrivate FcPtrSet * +FcPtrSetReference (FcPtrSet *set); + +FcPrivate void +FcPtrSetConst (FcPtrSet *set); + +FcPrivate void +FcPtrSetRefReset (FcPtrSet *set); + +FcPrivate FcBool +FcPtrSetFini (FcPtrSet *set); + +FcPrivate void +FcPtrSetDestroy (FcPtrSet *set); + +FcPrivate int +FcPtrSetGetSize (const FcPtrSet *set); + +FcPrivate void * +FcPtrSetIndex (const FcPtrSet *set, + int idx); + +FcPrivate int +FcPtrSetGetAllocatedSize (const FcPtrSet *set); + +FcPrivate void +FcPtrSetSort (FcPtrSet *set, + FcPtrSetCompareFunc func); + +FcPrivate FcBool +FcPtrSetAdd (FcPtrSet *set, + void *p); + +FcPrivate FcBool +FcPtrSetDel (FcPtrSet *set, + const void *p); + +FcPrivate FcBool +FcPtrSetMember (FcPtrSet *set, + const void *p); + +FcPrivate FcBool +FcPtrSetEqual (FcPtrSet *sa, + FcPtrSet *sb); + +FcPrivate FcPtrList * +FcPtrListInit (FcPtrList *list, + FcPtrSet *set); + +FcPrivate FcPtrList * +FcPtrListCreate (FcPtrSet *set); + +FcPrivate void +FcPtrListFirst (FcPtrList *list); + +FcPrivate void * +FcPtrListNext (FcPtrList *list); + +FcPrivate void +FcPtrListFini (FcPtrList *list); + +FcPrivate void +FcPtrListDone (FcPtrList *list); + /* fcrender.c */ /* fcmatrix.c */ @@ -1198,6 +1310,14 @@ FcRangeSerializeAlloc (FcSerialize *serialize, const FcRange *r); FcPrivate FcRange * FcRangeSerialize (FcSerialize *serialize, const FcRange *r); +/* fcscript.c */ + +FcPrivate FcScriptSet * +FcFreeTypeScriptSet (const FcCharSet *charset); + +FcPrivate FcBool +FcNameUnparseScriptSet (FcStrBuf *buf, const FcScriptSet *ss); + /* fcstat.c */ FcPrivate int @@ -1216,11 +1336,28 @@ FcIsFsMtimeBroken (const FcChar8 *dir); FcPrivate FcStrSet * FcStrSetCreateEx (unsigned int control); -FcPrivate FcBool -FcStrSetAddLangs (FcStrSet *strs, const char *languages); +FcPrivate int +FcStrSetGetSize (const FcStrSet *set); + +FcPrivate int +FcStrSetGetAllocatedSize (const FcStrSet *set); + +FcPrivate const FcChar8 * +FcStrSetIndex (const FcStrSet *set, + int idx); FcPrivate void -FcStrSetSort (FcStrSet * set); +FcStrSetConst (FcStrSet *set); + +FcPrivate void +FcStrSetRefReset (FcStrSet *set); + +FcPrivate void +FcStrSetSort (FcStrSet *set, + FcPtrSetCompareFunc func); + +FcPrivate FcBool +FcStrSetAddLangs (FcStrSet *strs, const char *languages); FcPrivate void FcStrBufInit (FcStrBuf *buf, FcChar8 *init, int size); diff --git a/src/fclang.c b/src/fclang.c index eadf34bf..a36821ed 100644 --- a/src/fclang.c +++ b/src/fclang.c @@ -24,6 +24,9 @@ #include "fcint.h" #include "fcftint.h" +#ifdef ENABLE_LIBLANGTAG +#include <liblangtag/langtag.h> +#endif /* Objects MT-safe for readonly access. */ @@ -468,6 +471,22 @@ FcGetLangs (void) return langs; } +void +FcLangInit (void) +{ +#ifdef ENABLE_LIBLANGTAG + lt_db_initialize (); +#endif +} + +void +FcLangFini (void) +{ +#ifdef ENABLE_LIBLANGTAG + lt_db_finalize (); +#endif +} + FcLangSet * FcLangSetCreate (void) { @@ -778,10 +797,10 @@ FcLangSetPromote (const FcChar8 *lang, FcValuePromotionBuffer *vbuf) else { buf->ls.extra = &buf->strs; - buf->strs.num = 1; - buf->strs.size = 1; - buf->strs.strs = &buf->str; - FcRefInit (&buf->strs.ref, 1); + buf->strs.ptrset.num = 1; + buf->strs.ptrset.size = 1; + buf->strs.ptrset.ptrs = (void **)&buf->str; + FcRefInit (&buf->strs.ptrset.ref, 1); buf->str = (FcChar8 *) lang; } } @@ -798,7 +817,7 @@ FcLangSetHash (const FcLangSet *ls) for (i = 0; i < count; i++) h ^= ls->map[i]; if (ls->extra) - h ^= ls->extra->num; + h ^= FcStrSetGetSize (ls->extra); return h; } diff --git a/src/fcscript.c b/src/fcscript.c new file mode 100644 index 00000000..cb630cb5 --- /dev/null +++ b/src/fcscript.c @@ -0,0 +1,247 @@ +/* + * fontconfig/src/fcscript.c + * + * Copyright © 2002 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the author(s) not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The authors make no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "fcint.h" +#include "fcftint.h" + +/* Objects MT-safe for readonly access. */ + +typedef struct { + const FcChar8 script[8]; + const FcCharSet charset; +} FcScriptCharSet; + +#include "../fc-script/fcscript.h" + +struct _FcScriptSet { + FcChar32 map_size; + FcChar32 map[NUM_SCRIPT_SET_MAP]; +}; + +static void +FcScriptSetBitSet (FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return; /* shouldn't happen really */ + + ss->map[bucket] |= ((FcChar32) 1 << (id & 0x1f)); +} + +static FcBool +FcScriptSetBitGet (const FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return FcFalse; + + return ((ss->map[bucket] >> (id & 0x1f)) & 1) ? FcTrue : FcFalse; +} + +static void +FcScriptSetBitReset (FcScriptSet *ss, + unsigned int id) +{ + unsigned int bucket; + + id = fcScriptCharSetIndices[id]; + bucket = id >> 5; + if (bucket >= ss->map_size) + return; /* shouldn't happen really */ + + ss->map[bucket] &= ~((FcChar32) 1 << (id & 0x1f)); +} + +FcScriptSet * +FcFreeTypeScriptSet (const FcCharSet *charset) +{ + static const int threshold = 60; + int i, j, avail; + FcChar32 missing, count; + FcScriptSet *ss; + + ss = FcScriptSetCreate (); + if (!ss) + return 0; + if (FcDebug() & FC_DBG_SCRIPTSET) + { + printf ("font scriptset"); + FcCharSetPrint (charset); + printf ("\n"); + } + for (i = 0; i < NUM_SCRIPT_CHAR_SET; i++) + { + if (FcDebug() & FC_DBG_SCRIPTSET) + { + printf ("%s charset", fcScriptCharSets[i].script); + FcCharSetPrint (&fcScriptCharSets[i].charset); + printf ("\n"); + } + +#if 0 + /* + * Check for Han charsets to make fonts + * which advertise support for a single language + * not support other Han languages + */ + if (exclusiveCharset && + FcFreeTypeIsExclusiveLang (fcLangCharSets[i].lang)) + { + if (fcLangCharSets[i].charset.num != exclusiveCharset->num) + continue; + + for (j = 0; j < fcLangCharSets[i].charset.num; j++) + if (FcCharSetLeaf(&fcLangCharSets[i].charset, j) != + FcCharSetLeaf(exclusiveCharset, j)) + continue; + } +#endif + count = FcCharSetCount (&fcScriptCharSets[i].charset); + missing = FcCharSetSubtractCount (&fcScriptCharSets[i].charset, charset); + avail = (count - missing) * 100 / count; + if (FcDebug() & FC_DBG_SCANV) + { + if (avail < threshold && missing < 10) + { + FcCharSet *missed = FcCharSetSubtract (&fcScriptCharSets[i].charset, + charset); + FcChar32 ucs4; + FcChar32 map[FC_CHARSET_MAP_SIZE]; + FcChar32 next; + + printf ("\n%s(%u) ", fcScriptCharSets[i].script, missing); + printf ("{"); + for (ucs4 = FcCharSetFirstPage (missed, map, &next); + ucs4 != FC_CHARSET_DONE; + ucs4 = FcCharSetNextPage (missed, map, &next)) + { + int i, j; + for (i = 0; i < FC_CHARSET_MAP_SIZE; i++) + if (map[i]) + { + for (j = 0; j < 32; j++) + if (map[i] & (1 << j)) + printf (" %04x", ucs4 + i * 32 + j); + } + } + printf (" }\n\t"); + FcCharSetDestroy (missed); + } + else + printf ("%s(%u) ", fcScriptCharSets[i].script, missing); + } + if (avail >= threshold) + FcScriptSetBitSet (ss, i); + } + + if (FcDebug() & FC_DBG_SCANV) + printf ("\n"); + + printf ("scriptset:\n"); + FcScriptSetPrint (ss); + printf ("\n"); + + return ss; +} + +const FcCharSet * +FcScriptGetCharSet (const FcChar8 *script) +{ + int i; + + for (i = 0; i < NUM_SCRIPT_CHAR_SET; i++) + { + if (FcStrCmpIgnoreCase (script, fcScriptCharSets[i].script) == 0) + { + volatile FcCharSet *cs = &fcScriptCharSets[i].charset; + printf("%p\n", cs); +// __asm__ volatile("int $03"); + return cs; +// return &fcScriptCharSets[i].charset; + } + } + + return NULL; +} + +FcScriptSet * +FcScriptSetCreate (void) +{ + FcScriptSet *ss; + + ss = malloc (sizeof (FcScriptSet)); + if (!ss) + return NULL; + memset (ss->map, '\0', sizeof (ss->map)); + ss->map_size = NUM_SCRIPT_SET_MAP; + + return ss; +} + +void +FcScriptSetDestroy (FcScriptSet *ss) +{ + free (ss); +} + +FcBool +FcNameUnparseScriptSet (FcStrBuf *buf, const FcScriptSet *ss) +{ + int i, bit, count; + FcChar32 bits; + FcBool first = FcTrue; + + count = FC_MIN (ss->map_size, NUM_SCRIPT_SET_MAP); + for (i = 0; i < count; i++) + { + if ((bits = ss->map[i])) + { + for (bit = 0; bit <= 31; bit++) + if (bits & (1 << bit)) + { + int id = (i << 5) | bit; + if (!first) + if (!FcStrBufChar (buf, '|')) + return FcFalse; + if (!FcStrBufString (buf, fcScriptCharSets[fcScriptCharSetIndicesInv[id]].script)) + return FcFalse; + first = FcFalse; + } + } + } + return FcTrue; +} + +#define __fcscript__ +#include "fcaliastail.h" +#include "fcftaliastail.h" +#undef __fcscript__ diff --git a/src/fcstr.c b/src/fcstr.c index b65492d8..8c64ac93 100644 --- a/src/fcstr.c +++ b/src/fcstr.c @@ -880,7 +880,7 @@ FcStrBuildFilename (const FcChar8 *path, if (!path) return NULL; - sset = FcStrSetCreateEx (FCSS_ALLOW_DUPLICATES | FCSS_GROW_BY_64); + sset = FcStrSetCreateEx (FC_SET_ALLOW_DUPLICATES | FC_SET_GROW_BY_64); if (!sset) return NULL; @@ -901,7 +901,7 @@ FcStrBuildFilename (const FcChar8 *path, { len += strlen ((const char *)s) + 1; } - list->n = 0; + FcStrListFirst (list); ret = malloc (sizeof (FcChar8) * (len + 1)); if (!ret) goto bail2; @@ -1130,96 +1130,56 @@ FcStrCanonFilename (const FcChar8 *s) FcStrSet * FcStrSetCreate (void) { - return FcStrSetCreateEx (FCSS_DEFAULT); + return FcStrSetCreateEx (FC_SET_DEFAULT); } FcStrSet * FcStrSetCreateEx (unsigned int control) { - FcStrSet *set = malloc (sizeof (FcStrSet)); - if (!set) - return 0; - FcRefInit (&set->ref, 1); - set->num = 0; - set->size = 0; - set->strs = 0; - set->control = control; - return set; + FcStrSet *set = malloc (sizeof (FcStrSet)); + + return (FcStrSet *) FcPtrSetInit (&set->ptrset, control, + (FcPtrSetDestroyFunc)FcStrFree, + (FcPtrSetCompareFunc)FcStrCmp); } -static FcBool -_FcStrSetGrow (FcStrSet *set, int growElements) +int +FcStrSetGetSize (const FcStrSet *set) { - /* 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; + return FcPtrSetGetSize (&set->ptrset); } -static FcBool -_FcStrSetAppend (FcStrSet *set, FcChar8 *s) +int +FcStrSetGetAllocatedSize (const FcStrSet *set) { - if (!FcStrSetHasControlBit (set, FCSS_ALLOW_DUPLICATES)) - { - if (FcStrSetMember (set, s)) - { - FcStrFree (s); - return FcTrue; - } - } - if (set->num == set->size) - { - 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; - return FcTrue; + return FcPtrSetGetAllocatedSize (&set->ptrset); +} + +const FcChar8 * +FcStrSetIndex (const FcStrSet *set, + int idx) +{ + return FcPtrSetIndex (&set->ptrset, idx); } FcBool FcStrSetMember (FcStrSet *set, const FcChar8 *s) { - int i; - - for (i = 0; i < set->num; i++) - if (!FcStrCmp (set->strs[i], s)) - return FcTrue; - return FcFalse; + return FcPtrSetMember (&set->ptrset, s); } FcBool FcStrSetEqual (FcStrSet *sa, FcStrSet *sb) { - int i; - if (sa->num != sb->num) - return FcFalse; - for (i = 0; i < sa->num; i++) - if (!FcStrSetMember (sb, sa->strs[i])) - return FcFalse; - return FcTrue; + return FcPtrSetEqual (&sa->ptrset, &sb->ptrset); } FcBool FcStrSetAdd (FcStrSet *set, const FcChar8 *s) { FcChar8 *new = FcStrCopy (s); - if (!new) - return FcFalse; - if (!_FcStrSetAppend (set, new)) - { - FcStrFree (new); - return FcFalse; - } - return FcTrue; + + return FcPtrSetAdd (&set->ptrset, new); } FcBool @@ -1228,12 +1188,8 @@ FcStrSetAddFilename (FcStrSet *set, const FcChar8 *s) FcChar8 *new = FcStrCopyFilename (s); if (!new) return FcFalse; - if (!_FcStrSetAppend (set, new)) - { - FcStrFree (new); - return FcFalse; - } - return FcTrue; + + return FcPtrSetAdd (&set->ptrset, new); } FcBool @@ -1283,52 +1239,40 @@ FcStrSetAddLangs (FcStrSet *strs, const char *languages) FcBool FcStrSetDel (FcStrSet *set, const FcChar8 *s) { - int i; - - for (i = 0; i < set->num; i++) - if (!FcStrCmp (set->strs[i], s)) - { - FcStrFree (set->strs[i]); - /* - * copy remaining string pointers and trailing - * NULL - */ - memmove (&set->strs[i], &set->strs[i+1], - (set->num - i) * sizeof (FcChar8 *)); - set->num--; - return FcTrue; - } - return FcFalse; + return FcPtrSetDel (&set->ptrset, s); } /* TODO Make public */ static FcStrSet * FcStrSetReference (FcStrSet *set) { - if (FcRefIsConst (&set->ref)) - return set; - - FcRefInc (&set->ref); - return set; + return (FcStrSet *) FcPtrSetReference (&set->ptrset); } void -FcStrSetDestroy (FcStrSet *set) +FcStrSetConst (FcStrSet *set) { - int i; + FcPtrSetConst (&set->ptrset); +} - /* We rely on this in FcGetDefaultLangs for caching. */ - if (FcRefIsConst (&set->ref)) - return; +void +FcStrSetRefReset (FcStrSet *set) +{ + FcPtrSetRefReset (&set->ptrset); +} - if (FcRefDec (&set->ref) != 1) - return; +void +FcStrSetDestroy (FcStrSet *set) +{ + if (FcPtrSetFini (&set->ptrset)) + free (set); +} - for (i = 0; i < set->num; i++) - FcStrFree (set->strs[i]); - if (set->strs) - free (set->strs); - free (set); +void +FcStrSetSort (FcStrSet *set, + FcPtrSetCompareFunc func) +{ + FcPtrSetSort (&set->ptrset, func); } FcStrList * @@ -1337,32 +1281,26 @@ FcStrListCreate (FcStrSet *set) FcStrList *list; list = malloc (sizeof (FcStrList)); - if (!list) - return 0; - list->set = set; - FcStrSetReference (set); - list->n = 0; - return list; + + return (FcStrList *) FcPtrListInit (&list->ptrlist, &set->ptrset); } void FcStrListFirst (FcStrList *list) { - list->n = 0; + FcPtrListFirst (&list->ptrlist); } FcChar8 * FcStrListNext (FcStrList *list) { - if (list->n >= list->set->num) - return 0; - return list->set->strs[list->n++]; + return FcPtrListNext (&list->ptrlist); } void FcStrListDone (FcStrList *list) { - FcStrSetDestroy (list->set); + FcPtrListFini (&list->ptrlist); free (list); } diff --git a/src/fcxml.c b/src/fcxml.c index 22b3211e..f0856f01 100644 --- a/src/fcxml.c +++ b/src/fcxml.c @@ -3190,7 +3190,7 @@ FcConfigParseAndLoadDir (FcConfig *config, strcat ((char *) file, "/"); base = file + strlen ((char *) file); - files = FcStrSetCreateEx (FCSS_GROW_BY_64); + files = FcStrSetCreateEx (FC_SET_GROW_BY_64); if (!files) { ret = FcFalse; @@ -3224,13 +3224,13 @@ FcConfigParseAndLoadDir (FcConfig *config, if (ret) { int i; - qsort (files->strs, files->num, sizeof (FcChar8 *), - (int (*)(const void *, const void *)) FcSortCmpStr); - for (i = 0; ret && i < files->num; i++) + + FcStrSetSort (files, FcSortCmpStr); + for (i = 0; ret && i < FcStrSetGetSize (files); i++) if (load) - ret = FcConfigParseAndLoad (config, files->strs[i], complain); + ret = FcConfigParseAndLoad (config, FcStrSetIndex (files, i), complain); else - ret = FcConfigParseOnly (config, files->strs[i], complain); + ret = FcConfigParseOnly (config, FcStrSetIndex (files, i), complain); } bail3: FcStrSetDestroy (files); |