]> git.wh0rd.org Git - fontconfig.git/blob - fc-match/fc-match.c
5ed8deff676b7e26e86829af3a796270478d5e37
[fontconfig.git] / fc-match / fc-match.c
1 /*
2  * fontconfig/fc-match/fc-match.c
3  *
4  * Copyright © 2003 Keith Packard
5  *
6  * Permission to use, copy, modify, distribute, and sell this software and its
7  * documentation for any purpose is hereby granted without fee, provided that
8  * the above copyright notice appear in all copies and that both that
9  * copyright notice and this permission notice appear in supporting
10  * documentation, and that the name of Keith Packard not be used in
11  * advertising or publicity pertaining to distribution of the software without
12  * specific, written prior permission.  Keith Packard makes no
13  * representations about the suitability of this software for any purpose.  It
14  * is provided "as is" without express or implied warranty.
15  *
16  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22  * PERFORMANCE OF THIS SOFTWARE.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #else
28 #ifdef linux
29 #define HAVE_GETOPT_LONG 1
30 #endif
31 #define HAVE_GETOPT 1
32 #endif
33
34 #include <fontconfig/fontconfig.h>
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #ifndef HAVE_GETOPT
41 #define HAVE_GETOPT 0
42 #endif
43 #ifndef HAVE_GETOPT_LONG
44 #define HAVE_GETOPT_LONG 0
45 #endif
46
47 #if HAVE_GETOPT_LONG
48 #undef  _GNU_SOURCE
49 #define _GNU_SOURCE
50 #include <getopt.h>
51 static const struct option longopts[] = {
52     {"sort", 0, 0, 's'},
53     {"all", 0, 0, 'a'},
54     {"version", 0, 0, 'V'},
55     {"verbose", 0, 0, 'v'},
56     {"help", 0, 0, 'h'},
57     {NULL,0,0,0},
58 };
59 #else
60 #if HAVE_GETOPT
61 extern char *optarg;
62 extern int optind, opterr, optopt;
63 #endif
64 #endif
65
66 static void
67 usage (char *program, int error)
68 {
69     FILE *file = error ? stderr : stdout;
70 #if HAVE_GETOPT_LONG
71     fprintf (file, "usage: %s [-savVh] [--sort] [--all] [--verbose] [--version] [--help] [pattern]\n",
72              program);
73 #else
74     fprintf (file, "usage: %s [-savVh] [pattern]\n",
75              program);
76 #endif
77     fprintf (file, "List fonts matching [pattern]\n");
78     fprintf (file, "\n");
79 #if HAVE_GETOPT_LONG
80     fprintf (file, "  -s, --sort           display sorted list of matches\n");
81     fprintf (file, "  -a, --all            display unpruned sorted list of matches\n");
82     fprintf (file, "  -v, --verbose        display entire font pattern\n");
83     fprintf (file, "  -V, --version        display font config version and exit\n");
84     fprintf (file, "  -h, --help           display this help and exit\n");
85 #else
86     fprintf (file, "  -s,        (sort)    display sorted list of matches\n");
87     fprintf (file, "  -a         (all)     display unpruned sorted list of matches\n");
88     fprintf (file, "  -v         (verbose) display entire font pattern\n");
89     fprintf (file, "  -V         (version) display font config version and exit\n");
90     fprintf (file, "  -h         (help)    display this help and exit\n");
91 #endif
92     exit (error);
93 }
94
95 int
96 main (int argc, char **argv)
97 {
98     int         verbose = 0;
99     int         sort = 0, all = 0;
100     int         i;
101     FcFontSet   *fs;
102     FcPattern   *pat;
103     FcResult    result;
104 #if HAVE_GETOPT_LONG || HAVE_GETOPT
105     int         c;
106
107 #if HAVE_GETOPT_LONG
108     while ((c = getopt_long (argc, argv, "asVvh", longopts, NULL)) != -1)
109 #else
110     while ((c = getopt (argc, argv, "asVvh")) != -1)
111 #endif
112     {
113         switch (c) {
114         case 'a':
115             all = 1;
116             break;
117         case 's':
118             sort = 1;
119             break;
120         case 'V':
121             fprintf (stderr, "fontconfig version %d.%d.%d\n", 
122                      FC_MAJOR, FC_MINOR, FC_REVISION);
123             exit (0);
124         case 'v':
125             verbose = 1;
126             break;
127         case 'h':
128             usage (argv[0], 0);
129         default:
130             usage (argv[0], 1);
131         }
132     }
133     i = optind;
134 #else
135     i = 1;
136 #endif
137
138     if (!FcInit ())
139     {
140         fprintf (stderr, "Can't init font config library\n");
141         return 1;
142     }
143     if (argv[i])
144         pat = FcNameParse ((FcChar8 *) argv[i]);
145     else
146         pat = FcPatternCreate ();
147
148     if (!pat)
149         return 1;
150
151     FcConfigSubstitute (0, pat, FcMatchPattern);
152     FcDefaultSubstitute (pat);
153     
154     fs = FcFontSetCreate ();
155
156     if (sort || all)
157     {
158         FcFontSet       *font_patterns;
159         int     j;
160         font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result);
161
162         for (j = 0; j < font_patterns->nfont; j++)
163         {
164             FcPattern  *font_pattern;
165
166             font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]);
167             if (font_pattern)
168                 FcFontSetAdd (fs, font_pattern);
169         }
170
171         FcFontSetSortDestroy (font_patterns);
172     }
173     else
174     {
175         FcPattern   *match;
176         match = FcFontMatch (0, pat, &result);
177         if (match)
178             FcFontSetAdd (fs, match);
179     }
180     FcPatternDestroy (pat);
181
182     if (fs)
183     {
184         int     j;
185
186         for (j = 0; j < fs->nfont; j++)
187         {
188             if (verbose)
189             {
190                 FcPatternPrint (fs->fonts[j]);
191             }
192             else
193             {
194                 FcChar8 *family;
195                 FcChar8 *style;
196                 FcChar8 *file;
197
198                 if (FcPatternGetString (fs->fonts[j], FC_FILE, 0, &file) != FcResultMatch)
199                     file = (FcChar8 *) "<unknown filename>";
200                 else
201                 {
202                     FcChar8 *slash = (FcChar8 *) strrchr ((char *) file, '/');
203                     if (slash)
204                         file = slash+1;
205                 }
206                 if (FcPatternGetString (fs->fonts[j], FC_FAMILY, 0, &family) != FcResultMatch)
207                     family = (FcChar8 *) "<unknown family>";
208                 if (FcPatternGetString (fs->fonts[j], FC_STYLE, 0, &style) != FcResultMatch)
209                     style = (FcChar8 *) "<unknown style>";
210
211                 printf ("%s: \"%s\" \"%s\"\n", file, family, style);
212             }
213         }
214         FcFontSetDestroy (fs);
215     }
216     FcFini ();
217     return 0;
218 }