From 62798ca7e5a73d04e138baef11fff410dc7eb7d4 Mon Sep 17 00:00:00 2001 From: Akira TAGOH Date: Thu, 24 May 2012 13:50:48 +0900 Subject: Add an API to create charset from string Also add --string option to fc-match to compute the best font from the given string --- fc-match/fc-match.c | 24 +++++++++++++++++++----- fontconfig/fontconfig.h | 4 ++++ src/fccharset.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/fc-match/fc-match.c b/fc-match/fc-match.c index dee61479..ee95f7d8 100644 --- a/fc-match/fc-match.c +++ b/fc-match/fc-match.c @@ -63,6 +63,7 @@ static const struct option longopts[] = { {"verbose", 0, 0, 'v'}, {"brief", 0, 0, 'b'}, {"format", 1, 0, 'f'}, + {"string", 1, 0, 'r'}, {"version", 0, 0, 'V'}, {"help", 0, 0, 'h'}, {NULL,0,0,0}, @@ -79,10 +80,10 @@ usage (char *program, int error) { FILE *file = error ? stderr : stdout; #if HAVE_GETOPT_LONG - fprintf (file, _("usage: %s [-savbVh] [-f FORMAT] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n"), + fprintf (file, _("usage: %s [-savbVh] [-f FORMAT] [-r STRING] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--string=STRING] [--version] [--help] [pattern] {element...}\n"), program); #else - fprintf (file, _("usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n"), + fprintf (file, _("usage: %s [-savVh] [-f FORMAT] [-r STRING] [pattern] {element...}\n"), program); #endif fprintf (file, _("List best font matching [pattern]\n")); @@ -93,6 +94,7 @@ usage (char *program, int error) fprintf (file, _(" -v, --verbose display entire font pattern verbosely\n")); fprintf (file, _(" -b, --brief display entire font pattern briefly\n")); fprintf (file, _(" -f, --format=FORMAT use the given output format\n")); + fprintf (file, _(" -r, --string=STRING compute the best font for STRING\n")); fprintf (file, _(" -V, --version display font config version and exit\n")); fprintf (file, _(" -h, --help display this help and exit\n")); #else @@ -101,6 +103,7 @@ usage (char *program, int error) fprintf (file, _(" -v (verbose) display entire font pattern verbosely\n")); fprintf (file, _(" -b (brief) display entire font pattern briefly\n")); fprintf (file, _(" -f FORMAT (format) use the given output format\n")); + fprintf (file, _(" -r STRING (string) compute the best font for STRING\n")); fprintf (file, _(" -V (version) display font config version and exit\n")); fprintf (file, _(" -h (help) display this help and exit\n")); #endif @@ -113,20 +116,21 @@ main (int argc, char **argv) int verbose = 0; int brief = 0; int sort = 0, all = 0; - const FcChar8 *format = NULL; + const FcChar8 *format = NULL, *string = NULL; int i; FcObjectSet *os = 0; FcFontSet *fs; FcPattern *pat; FcResult result; + FcCharSet *fcs; #if HAVE_GETOPT_LONG || HAVE_GETOPT int c; setlocale (LC_ALL, ""); #if HAVE_GETOPT_LONG - while ((c = getopt_long (argc, argv, "asvbf:Vh", longopts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "asvbf:r:Vh", longopts, NULL)) != -1) #else - while ((c = getopt (argc, argv, "asvbf:Vh")) != -1) + while ((c = getopt (argc, argv, "asvbf:r:Vh")) != -1) #endif { switch (c) { @@ -145,6 +149,9 @@ main (int argc, char **argv) case 'f': format = (FcChar8 *) strdup (optarg); break; + case 'r': + string = (FcChar8 *) strdup (optarg); + break; case 'V': fprintf (stderr, "fontconfig version %d.%d.%d\n", FC_MAJOR, FC_MINOR, FC_REVISION); @@ -181,6 +188,13 @@ main (int argc, char **argv) if (!pat) return 1; + if (string) + { + fcs = FcCharSetCreateFromString (string, -1); + if (fcs) + FcPatternAddCharSet (pat, FC_CHARSET, fcs); + } + FcConfigSubstitute (0, pat, FcMatchPattern); FcDefaultSubstitute (pat); diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h index 5c04219e..0cf95026 100644 --- a/fontconfig/fontconfig.h +++ b/fontconfig/fontconfig.h @@ -547,6 +547,10 @@ FcCharSetNextPage (const FcCharSet *a, FcChar32 map[FC_CHARSET_MAP_SIZE], FcChar32 *next); +FcCharSet * +FcCharSetCreateFromString (const FcChar8 *strings, + ssize_t len); + /* * old coverage API, rather hard to use correctly */ diff --git a/src/fccharset.c b/src/fccharset.c index 114f9484..370e4e1b 100644 --- a/src/fccharset.c +++ b/src/fccharset.c @@ -1395,6 +1395,42 @@ FcCharSetSerialize(FcSerialize *serialize, const FcCharSet *cs) return cs_serialized; } + +FcCharSet * +FcCharSetCreateFromString (const FcChar8 *strings, + ssize_t len) +{ + ssize_t i; + FcChar32 c; + int clen; + FcCharSet *fcs; + + if (!strings || strings[0] == '\0' || len == 0) + return NULL; + + if (len < 0) + len = strlen ((const char *)strings); + + fcs = FcCharSetCreate (); + i = 0; + while (i < len) + { + clen = FcUtf8ToUcs4 (&strings[i], &c, len - i); + if (clen <= 0) /* malformed UTF-8 string */ + goto bail; + i += clen; + if (!FcCharSetAddChar (fcs, c)) + goto bail; + } + + return fcs; + bail: + if (fcs) + FcCharSetDestroy (fcs); + + return NULL; +} + #define __fccharset__ #include "fcaliastail.h" #undef __fccharset__ -- cgit v1.2.3