fc-match.c 6.53 KB
Newer Older
Keith Packard's avatar
Keith Packard committed
1
/*
2
 * fontconfig/fc-match/fc-match.c
Keith Packard's avatar
Keith Packard committed
3
 *
4
 * Copyright © 2003 Keith Packard
Keith Packard's avatar
Keith Packard committed
5 6 7 8 9
 *
 * 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
10
 * documentation, and that the name of the author(s) not be used in
Keith Packard's avatar
Keith Packard committed
11
 * advertising or publicity pertaining to distribution of the software without
12
 * specific, written prior permission.  The authors make no
Keith Packard's avatar
Keith Packard committed
13 14 15
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
16
 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Keith Packard's avatar
Keith Packard committed
17
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
 * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Keith Packard's avatar
Keith Packard committed
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#else
#ifdef linux
#define HAVE_GETOPT_LONG 1
#endif
#define HAVE_GETOPT 1
#endif

34 35 36 37 38
#include <fontconfig/fontconfig.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
Akira TAGOH's avatar
Akira TAGOH committed
39
#include <locale.h>
40

41 42 43 44 45 46 47 48
#ifdef ENABLE_NLS
#include <libintl.h>
#define _(x)		(dgettext(GETTEXT_PACKAGE, x))
#else
#define dgettext(d, s)	(s)
#define _(x)		(x)
#endif

Keith Packard's avatar
Keith Packard committed
49 50 51 52 53 54 55 56 57 58 59
#ifndef HAVE_GETOPT
#define HAVE_GETOPT 0
#endif
#ifndef HAVE_GETOPT_LONG
#define HAVE_GETOPT_LONG 0
#endif

#if HAVE_GETOPT_LONG
#undef  _GNU_SOURCE
#define _GNU_SOURCE
#include <getopt.h>
60
static const struct option longopts[] = {
Keith Packard's avatar
Keith Packard committed
61
    {"sort", 0, 0, 's'},
62
    {"all", 0, 0, 'a'},
Keith Packard's avatar
Keith Packard committed
63
    {"verbose", 0, 0, 'v'},
64
    {"brief", 0, 0, 'b'},
65 66
    {"format", 1, 0, 'f'},
    {"version", 0, 0, 'V'},
67
    {"help", 0, 0, 'h'},
Keith Packard's avatar
Keith Packard committed
68 69 70 71 72 73 74 75 76
    {NULL,0,0,0},
};
#else
#if HAVE_GETOPT
extern char *optarg;
extern int optind, opterr, optopt;
#endif
#endif

77 78
static void
usage (char *program, int error)
Keith Packard's avatar
Keith Packard committed
79
{
80
    FILE *file = error ? stderr : stdout;
Keith Packard's avatar
Keith Packard committed
81
#if HAVE_GETOPT_LONG
82
    fprintf (file, _("usage: %s [-savbVh] [-f FORMAT] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n"),
Keith Packard's avatar
Keith Packard committed
83 84
	     program);
#else
85
    fprintf (file, _("usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n"),
Keith Packard's avatar
Keith Packard committed
86 87
	     program);
#endif
88
    fprintf (file, _("List best font matching [pattern]\n"));
89
    fprintf (file, "\n");
Keith Packard's avatar
Keith Packard committed
90
#if HAVE_GETOPT_LONG
91 92 93 94 95 96 97
    fprintf (file, _("  -s, --sort           display sorted list of matches\n"));
    fprintf (file, _("  -a, --all            display unpruned sorted list of matches\n"));
    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, _("  -V, --version        display font config version and exit\n"));
    fprintf (file, _("  -h, --help           display this help and exit\n"));
Keith Packard's avatar
Keith Packard committed
98
#else
99 100 101 102 103 104 105
    fprintf (file, _("  -s,        (sort)    display sorted list of matches\n"));
    fprintf (file, _("  -a         (all)     display unpruned sorted list of matches\n"));
    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, _("  -V         (version) display font config version and exit\n"));
    fprintf (file, _("  -h         (help)    display this help and exit\n"));
Keith Packard's avatar
Keith Packard committed
106
#endif
107
    exit (error);
Keith Packard's avatar
Keith Packard committed
108 109 110 111 112
}

int
main (int argc, char **argv)
{
113
    int			verbose = 0;
114
    int			brief = 0;
115 116 117 118 119 120 121
    int			sort = 0, all = 0;
    const FcChar8	*format = NULL;
    int			i;
    FcObjectSet		*os = 0;
    FcFontSet		*fs;
    FcPattern		*pat;
    FcResult		result;
Keith Packard's avatar
Keith Packard committed
122
#if HAVE_GETOPT_LONG || HAVE_GETOPT
123
    int			c;
Keith Packard's avatar
Keith Packard committed
124

Akira TAGOH's avatar
Akira TAGOH committed
125
    setlocale (LC_ALL, "");
Keith Packard's avatar
Keith Packard committed
126
#if HAVE_GETOPT_LONG
127
    while ((c = getopt_long (argc, argv, "asvbf:Vh", longopts, NULL)) != -1)
Keith Packard's avatar
Keith Packard committed
128
#else
129
    while ((c = getopt (argc, argv, "asvbf:Vh")) != -1)
Keith Packard's avatar
Keith Packard committed
130 131 132
#endif
    {
	switch (c) {
133 134 135
	case 'a':
	    all = 1;
	    break;
Keith Packard's avatar
Keith Packard committed
136 137 138
	case 's':
	    sort = 1;
	    break;
139 140 141
	case 'v':
	    verbose = 1;
	    break;
142 143 144
	case 'b':
	    brief = 1;
	    break;
145 146 147
	case 'f':
	    format = (FcChar8 *) strdup (optarg);
	    break;
Keith Packard's avatar
Keith Packard committed
148 149 150 151
	case 'V':
	    fprintf (stderr, "fontconfig version %d.%d.%d\n", 
		     FC_MAJOR, FC_MINOR, FC_REVISION);
	    exit (0);
152 153
	case 'h':
	    usage (argv[0], 0);
Keith Packard's avatar
Keith Packard committed
154
	default:
155
	    usage (argv[0], 1);
Keith Packard's avatar
Keith Packard committed
156 157 158 159 160 161 162 163
	}
    }
    i = optind;
#else
    i = 1;
#endif

    if (argv[i])
164
    {
Keith Packard's avatar
Keith Packard committed
165
	pat = FcNameParse ((FcChar8 *) argv[i]);
166 167
	if (!pat)
	{
168
	    fprintf (stderr, _("Unable to parse the pattern\n"));
169 170
	    return 1;
	}
171 172 173 174 175 176 177
	while (argv[++i])
	{
	    if (!os)
		os = FcObjectSetCreate ();
	    FcObjectSetAdd (os, argv[i]);
	}
    }
Keith Packard's avatar
Keith Packard committed
178 179 180
    else
	pat = FcPatternCreate ();

181 182 183
    if (!pat)
	return 1;

Keith Packard's avatar
Keith Packard committed
184 185 186
    FcConfigSubstitute (0, pat, FcMatchPattern);
    FcDefaultSubstitute (pat);
    
187 188
    fs = FcFontSetCreate ();

189
    if (sort || all)
190 191 192
    {
	FcFontSet	*font_patterns;
	int	j;
193
	font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result);
194

195 196
	if (!font_patterns || font_patterns->nfont == 0)
	{
197
	    fprintf (stderr, _("No fonts installed on the system\n"));
198 199
	    return 1;
	}
200 201 202 203 204 205 206 207 208 209 210
	for (j = 0; j < font_patterns->nfont; j++)
	{
	    FcPattern  *font_pattern;

	    font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]);
	    if (font_pattern)
		FcFontSetAdd (fs, font_pattern);
	}

	FcFontSetSortDestroy (font_patterns);
    }
Keith Packard's avatar
Keith Packard committed
211 212 213 214 215 216 217
    else
    {
	FcPattern   *match;
	match = FcFontMatch (0, pat, &result);
	if (match)
	    FcFontSetAdd (fs, match);
    }
218
    FcPatternDestroy (pat);
Keith Packard's avatar
Keith Packard committed
219

220 221 222
    if (!format)
    {
	if (os)
223
	    format = (const FcChar8 *) "%{=unparse}\n";
224
	else
225
	    format = (const FcChar8 *) "%{=fcmatch}\n";
226 227
    }

Keith Packard's avatar
Keith Packard committed
228 229 230 231 232 233
    if (fs)
    {
	int	j;

	for (j = 0; j < fs->nfont; j++)
	{
234 235 236 237
	    FcPattern *font;

	    font = FcPatternFilter (fs->fonts[j], os);

238
	    if (verbose || brief)
Keith Packard's avatar
Keith Packard committed
239
	    {
240 241 242 243 244
		if (brief)
		{
		    FcPatternDel (font, FC_CHARSET);
		    FcPatternDel (font, FC_LANG);
		}
245
		FcPatternPrint (font);
Keith Packard's avatar
Keith Packard committed
246
	    }
247
	    else
248 249 250
	    {
	        FcChar8 *s;

251
		s = FcPatternFormat (font, format);
252 253 254
		if (s)
		{
		    printf ("%s", s);
255
		    FcStrFree (s);
256
		}
257
	    }
258 259

	    FcPatternDestroy (font);
Keith Packard's avatar
Keith Packard committed
260 261 262
	}
	FcFontSetDestroy (fs);
    }
263 264 265 266

    if (os)
	FcObjectSetDestroy (os);

267
    FcFini ();
268

Keith Packard's avatar
Keith Packard committed
269 270
    return 0;
}