1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2002 Keith Packard
3*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2014 Google, Inc.
4*2d1272b8SAndroid Build Coastguard Worker *
5*2d1272b8SAndroid Build Coastguard Worker * Permission to use, copy, modify, distribute, and sell this software and its
6*2d1272b8SAndroid Build Coastguard Worker * documentation for any purpose is hereby granted without fee, provided that
7*2d1272b8SAndroid Build Coastguard Worker * the above copyright notice appear in all copies and that both that
8*2d1272b8SAndroid Build Coastguard Worker * copyright notice and this permission notice appear in supporting
9*2d1272b8SAndroid Build Coastguard Worker * documentation, and that the name of the author(s) not be used in
10*2d1272b8SAndroid Build Coastguard Worker * advertising or publicity pertaining to distribution of the software without
11*2d1272b8SAndroid Build Coastguard Worker * specific, written prior permission. The authors make no
12*2d1272b8SAndroid Build Coastguard Worker * representations about the suitability of this software for any purpose. It
13*2d1272b8SAndroid Build Coastguard Worker * is provided "as is" without express or implied warranty.
14*2d1272b8SAndroid Build Coastguard Worker *
15*2d1272b8SAndroid Build Coastguard Worker * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16*2d1272b8SAndroid Build Coastguard Worker * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17*2d1272b8SAndroid Build Coastguard Worker * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18*2d1272b8SAndroid Build Coastguard Worker * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19*2d1272b8SAndroid Build Coastguard Worker * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20*2d1272b8SAndroid Build Coastguard Worker * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21*2d1272b8SAndroid Build Coastguard Worker * PERFORMANCE OF THIS SOFTWARE.
22*2d1272b8SAndroid Build Coastguard Worker *
23*2d1272b8SAndroid Build Coastguard Worker * Google Author(s): Behdad Esfahbod
24*2d1272b8SAndroid Build Coastguard Worker */
25*2d1272b8SAndroid Build Coastguard Worker
26*2d1272b8SAndroid Build Coastguard Worker #define HAVE_GETOPT_LONG 1 /* XXX */
27*2d1272b8SAndroid Build Coastguard Worker
28*2d1272b8SAndroid Build Coastguard Worker #include "hb-fc.h"
29*2d1272b8SAndroid Build Coastguard Worker
30*2d1272b8SAndroid Build Coastguard Worker #include <fontconfig/fontconfig.h>
31*2d1272b8SAndroid Build Coastguard Worker #include <stdio.h>
32*2d1272b8SAndroid Build Coastguard Worker #include <unistd.h>
33*2d1272b8SAndroid Build Coastguard Worker #include <stdlib.h>
34*2d1272b8SAndroid Build Coastguard Worker #include <string.h>
35*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
36*2d1272b8SAndroid Build Coastguard Worker #include <config.h>
37*2d1272b8SAndroid Build Coastguard Worker #else
38*2d1272b8SAndroid Build Coastguard Worker #ifdef linux
39*2d1272b8SAndroid Build Coastguard Worker #define HAVE_GETOPT_LONG 1
40*2d1272b8SAndroid Build Coastguard Worker #endif
41*2d1272b8SAndroid Build Coastguard Worker #define HAVE_GETOPT 1
42*2d1272b8SAndroid Build Coastguard Worker #endif
43*2d1272b8SAndroid Build Coastguard Worker
44*2d1272b8SAndroid Build Coastguard Worker #ifndef HAVE_GETOPT
45*2d1272b8SAndroid Build Coastguard Worker #define HAVE_GETOPT 0
46*2d1272b8SAndroid Build Coastguard Worker #endif
47*2d1272b8SAndroid Build Coastguard Worker #ifndef HAVE_GETOPT_LONG
48*2d1272b8SAndroid Build Coastguard Worker #define HAVE_GETOPT_LONG 0
49*2d1272b8SAndroid Build Coastguard Worker #endif
50*2d1272b8SAndroid Build Coastguard Worker
51*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
52*2d1272b8SAndroid Build Coastguard Worker #undef _GNU_SOURCE
53*2d1272b8SAndroid Build Coastguard Worker #define _GNU_SOURCE
54*2d1272b8SAndroid Build Coastguard Worker #include <getopt.h>
55*2d1272b8SAndroid Build Coastguard Worker const struct option longopts[] = {
56*2d1272b8SAndroid Build Coastguard Worker {"verbose", 0, 0, 'v'},
57*2d1272b8SAndroid Build Coastguard Worker {"format", 1, 0, 'f'},
58*2d1272b8SAndroid Build Coastguard Worker {"quiet", 0, 0, 'q'},
59*2d1272b8SAndroid Build Coastguard Worker {"version", 0, 0, 'V'},
60*2d1272b8SAndroid Build Coastguard Worker {"help", 0, 0, 'h'},
61*2d1272b8SAndroid Build Coastguard Worker {NULL,0,0,0},
62*2d1272b8SAndroid Build Coastguard Worker };
63*2d1272b8SAndroid Build Coastguard Worker #else
64*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT
65*2d1272b8SAndroid Build Coastguard Worker extern char *optarg;
66*2d1272b8SAndroid Build Coastguard Worker extern int optind, opterr, optopt;
67*2d1272b8SAndroid Build Coastguard Worker #endif
68*2d1272b8SAndroid Build Coastguard Worker #endif
69*2d1272b8SAndroid Build Coastguard Worker
70*2d1272b8SAndroid Build Coastguard Worker static void
usage(char * program,int error)71*2d1272b8SAndroid Build Coastguard Worker usage (char *program, int error)
72*2d1272b8SAndroid Build Coastguard Worker {
73*2d1272b8SAndroid Build Coastguard Worker FILE *file = error ? stderr : stdout;
74*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
75*2d1272b8SAndroid Build Coastguard Worker fprintf (file, "usage: %s [-vqVh] [-f FORMAT] [--verbose] [--format=FORMAT] [--quiet] [--version] [--help] text [pattern] {element ...} \n",
76*2d1272b8SAndroid Build Coastguard Worker program);
77*2d1272b8SAndroid Build Coastguard Worker #else
78*2d1272b8SAndroid Build Coastguard Worker fprintf (file, "usage: %s [-vqVh] [-f FORMAT] text [pattern] {element ...} \n",
79*2d1272b8SAndroid Build Coastguard Worker program);
80*2d1272b8SAndroid Build Coastguard Worker #endif
81*2d1272b8SAndroid Build Coastguard Worker fprintf (file, "List fonts matching [pattern] that can render [text]\n");
82*2d1272b8SAndroid Build Coastguard Worker fprintf (file, "\n");
83*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
84*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -v, --verbose display entire font pattern verbosely\n");
85*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -f, --format=FORMAT use the given output format\n");
86*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -q, --quiet suppress all normal output, exit 1 if no fonts matched\n");
87*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -V, --version display font config version and exit\n");
88*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -h, --help display this help and exit\n");
89*2d1272b8SAndroid Build Coastguard Worker #else
90*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -v (verbose) display entire font pattern verbosely\n");
91*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -f FORMAT (format) use the given output format\n");
92*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -q, (quiet) suppress all normal output, exit 1 if no fonts matched\n");
93*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -V (version) display HarfBuzz version and exit\n");
94*2d1272b8SAndroid Build Coastguard Worker fprintf (file, " -h (help) display this help and exit\n");
95*2d1272b8SAndroid Build Coastguard Worker #endif
96*2d1272b8SAndroid Build Coastguard Worker exit (error);
97*2d1272b8SAndroid Build Coastguard Worker }
98*2d1272b8SAndroid Build Coastguard Worker
99*2d1272b8SAndroid Build Coastguard Worker int
main(int argc,char ** argv)100*2d1272b8SAndroid Build Coastguard Worker main (int argc, char **argv)
101*2d1272b8SAndroid Build Coastguard Worker {
102*2d1272b8SAndroid Build Coastguard Worker int verbose = 0;
103*2d1272b8SAndroid Build Coastguard Worker int quiet = 0;
104*2d1272b8SAndroid Build Coastguard Worker const FcChar8 *format = NULL;
105*2d1272b8SAndroid Build Coastguard Worker int nfont = 0;
106*2d1272b8SAndroid Build Coastguard Worker int i;
107*2d1272b8SAndroid Build Coastguard Worker FcObjectSet *os = 0;
108*2d1272b8SAndroid Build Coastguard Worker FcFontSet *fs;
109*2d1272b8SAndroid Build Coastguard Worker FcPattern *pat;
110*2d1272b8SAndroid Build Coastguard Worker const char *text;
111*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG || HAVE_GETOPT
112*2d1272b8SAndroid Build Coastguard Worker int c;
113*2d1272b8SAndroid Build Coastguard Worker
114*2d1272b8SAndroid Build Coastguard Worker #if HAVE_GETOPT_LONG
115*2d1272b8SAndroid Build Coastguard Worker while ((c = getopt_long (argc, argv, "vf:qVh", longopts, NULL)) != -1)
116*2d1272b8SAndroid Build Coastguard Worker #else
117*2d1272b8SAndroid Build Coastguard Worker while ((c = getopt (argc, argv, "vf:qVh")) != -1)
118*2d1272b8SAndroid Build Coastguard Worker #endif
119*2d1272b8SAndroid Build Coastguard Worker {
120*2d1272b8SAndroid Build Coastguard Worker switch (c) {
121*2d1272b8SAndroid Build Coastguard Worker case 'v':
122*2d1272b8SAndroid Build Coastguard Worker verbose = 1;
123*2d1272b8SAndroid Build Coastguard Worker break;
124*2d1272b8SAndroid Build Coastguard Worker case 'f':
125*2d1272b8SAndroid Build Coastguard Worker format = (FcChar8 *) strdup (optarg);
126*2d1272b8SAndroid Build Coastguard Worker break;
127*2d1272b8SAndroid Build Coastguard Worker case 'q':
128*2d1272b8SAndroid Build Coastguard Worker quiet = 1;
129*2d1272b8SAndroid Build Coastguard Worker break;
130*2d1272b8SAndroid Build Coastguard Worker case 'V':
131*2d1272b8SAndroid Build Coastguard Worker fprintf (stderr, "fontconfig version %d.%d.%d\n",
132*2d1272b8SAndroid Build Coastguard Worker FC_MAJOR, FC_MINOR, FC_REVISION);
133*2d1272b8SAndroid Build Coastguard Worker exit (0);
134*2d1272b8SAndroid Build Coastguard Worker case 'h':
135*2d1272b8SAndroid Build Coastguard Worker usage (argv[0], 0);
136*2d1272b8SAndroid Build Coastguard Worker default:
137*2d1272b8SAndroid Build Coastguard Worker usage (argv[0], 1);
138*2d1272b8SAndroid Build Coastguard Worker }
139*2d1272b8SAndroid Build Coastguard Worker }
140*2d1272b8SAndroid Build Coastguard Worker i = optind;
141*2d1272b8SAndroid Build Coastguard Worker #else
142*2d1272b8SAndroid Build Coastguard Worker i = 1;
143*2d1272b8SAndroid Build Coastguard Worker #endif
144*2d1272b8SAndroid Build Coastguard Worker
145*2d1272b8SAndroid Build Coastguard Worker if (!argv[i])
146*2d1272b8SAndroid Build Coastguard Worker usage (argv[0], 1);
147*2d1272b8SAndroid Build Coastguard Worker
148*2d1272b8SAndroid Build Coastguard Worker text = argv[i];
149*2d1272b8SAndroid Build Coastguard Worker i++;
150*2d1272b8SAndroid Build Coastguard Worker
151*2d1272b8SAndroid Build Coastguard Worker if (argv[i])
152*2d1272b8SAndroid Build Coastguard Worker {
153*2d1272b8SAndroid Build Coastguard Worker pat = FcNameParse ((FcChar8 *) argv[i]);
154*2d1272b8SAndroid Build Coastguard Worker if (!pat)
155*2d1272b8SAndroid Build Coastguard Worker {
156*2d1272b8SAndroid Build Coastguard Worker fputs ("Unable to parse the pattern\n", stderr);
157*2d1272b8SAndroid Build Coastguard Worker return 1;
158*2d1272b8SAndroid Build Coastguard Worker }
159*2d1272b8SAndroid Build Coastguard Worker while (argv[++i])
160*2d1272b8SAndroid Build Coastguard Worker {
161*2d1272b8SAndroid Build Coastguard Worker if (!os)
162*2d1272b8SAndroid Build Coastguard Worker os = FcObjectSetCreate ();
163*2d1272b8SAndroid Build Coastguard Worker FcObjectSetAdd (os, argv[i]);
164*2d1272b8SAndroid Build Coastguard Worker }
165*2d1272b8SAndroid Build Coastguard Worker }
166*2d1272b8SAndroid Build Coastguard Worker else
167*2d1272b8SAndroid Build Coastguard Worker pat = FcPatternCreate ();
168*2d1272b8SAndroid Build Coastguard Worker if (quiet && !os)
169*2d1272b8SAndroid Build Coastguard Worker os = FcObjectSetCreate ();
170*2d1272b8SAndroid Build Coastguard Worker if (!verbose && !format && !os)
171*2d1272b8SAndroid Build Coastguard Worker os = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_FILE, (char *) 0);
172*2d1272b8SAndroid Build Coastguard Worker FcObjectSetAdd (os, FC_CHARSET);
173*2d1272b8SAndroid Build Coastguard Worker if (!format)
174*2d1272b8SAndroid Build Coastguard Worker format = (const FcChar8 *) "%{=fclist}\n";
175*2d1272b8SAndroid Build Coastguard Worker fs = FcFontList (0, pat, os);
176*2d1272b8SAndroid Build Coastguard Worker if (os)
177*2d1272b8SAndroid Build Coastguard Worker FcObjectSetDestroy (os);
178*2d1272b8SAndroid Build Coastguard Worker if (pat)
179*2d1272b8SAndroid Build Coastguard Worker FcPatternDestroy (pat);
180*2d1272b8SAndroid Build Coastguard Worker
181*2d1272b8SAndroid Build Coastguard Worker if (!quiet && fs)
182*2d1272b8SAndroid Build Coastguard Worker {
183*2d1272b8SAndroid Build Coastguard Worker int j;
184*2d1272b8SAndroid Build Coastguard Worker
185*2d1272b8SAndroid Build Coastguard Worker for (j = 0; j < fs->nfont; j++)
186*2d1272b8SAndroid Build Coastguard Worker {
187*2d1272b8SAndroid Build Coastguard Worker hb_font_t *font = hb_fc_font_create (fs->fonts[j]);
188*2d1272b8SAndroid Build Coastguard Worker hb_bool_t can_render = hb_fc_can_render (font, text);
189*2d1272b8SAndroid Build Coastguard Worker hb_font_destroy (font);
190*2d1272b8SAndroid Build Coastguard Worker
191*2d1272b8SAndroid Build Coastguard Worker if (!can_render)
192*2d1272b8SAndroid Build Coastguard Worker continue;
193*2d1272b8SAndroid Build Coastguard Worker
194*2d1272b8SAndroid Build Coastguard Worker FcPatternDel (fs->fonts[j], FC_CHARSET);
195*2d1272b8SAndroid Build Coastguard Worker
196*2d1272b8SAndroid Build Coastguard Worker if (verbose)
197*2d1272b8SAndroid Build Coastguard Worker {
198*2d1272b8SAndroid Build Coastguard Worker FcPatternPrint (fs->fonts[j]);
199*2d1272b8SAndroid Build Coastguard Worker }
200*2d1272b8SAndroid Build Coastguard Worker else
201*2d1272b8SAndroid Build Coastguard Worker {
202*2d1272b8SAndroid Build Coastguard Worker FcChar8 *s;
203*2d1272b8SAndroid Build Coastguard Worker
204*2d1272b8SAndroid Build Coastguard Worker s = FcPatternFormat (fs->fonts[j], format);
205*2d1272b8SAndroid Build Coastguard Worker if (s)
206*2d1272b8SAndroid Build Coastguard Worker {
207*2d1272b8SAndroid Build Coastguard Worker printf ("%s", s);
208*2d1272b8SAndroid Build Coastguard Worker FcStrFree (s);
209*2d1272b8SAndroid Build Coastguard Worker }
210*2d1272b8SAndroid Build Coastguard Worker }
211*2d1272b8SAndroid Build Coastguard Worker }
212*2d1272b8SAndroid Build Coastguard Worker }
213*2d1272b8SAndroid Build Coastguard Worker
214*2d1272b8SAndroid Build Coastguard Worker if (fs) {
215*2d1272b8SAndroid Build Coastguard Worker nfont = fs->nfont;
216*2d1272b8SAndroid Build Coastguard Worker FcFontSetDestroy (fs);
217*2d1272b8SAndroid Build Coastguard Worker }
218*2d1272b8SAndroid Build Coastguard Worker
219*2d1272b8SAndroid Build Coastguard Worker FcFini ();
220*2d1272b8SAndroid Build Coastguard Worker
221*2d1272b8SAndroid Build Coastguard Worker return quiet ? (nfont == 0 ? 1 : 0) : 0;
222*2d1272b8SAndroid Build Coastguard Worker }
223