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 the author(s) not be used in 11 * advertising or publicity pertaining to distribution of the software without 12 * specific, written prior permission. The authors make 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 * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18 * EVENT SHALL THE AUTHOR(S) 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 <stdlib.h> 37#include <string.h> 38#include <locale.h> 39 40#ifdef HAVE_UNISTD_H 41#include <unistd.h> 42#endif 43 44#ifdef ENABLE_NLS 45#include <libintl.h> 46#define _(x) (dgettext(GETTEXT_PACKAGE, x)) 47#else 48#define dgettext(d, s) (s) 49#define _(x) (x) 50#endif 51 52#ifndef HAVE_GETOPT 53#define HAVE_GETOPT 0 54#endif 55#ifndef HAVE_GETOPT_LONG 56#define HAVE_GETOPT_LONG 0 57#endif 58 59#if HAVE_GETOPT_LONG 60#undef _GNU_SOURCE 61#define _GNU_SOURCE 62#include <getopt.h> 63static const struct option longopts[] = { 64 {"sort", 0, 0, 's'}, 65 {"all", 0, 0, 'a'}, 66 {"verbose", 0, 0, 'v'}, 67 {"brief", 0, 0, 'b'}, 68 {"format", 1, 0, 'f'}, 69 {"version", 0, 0, 'V'}, 70 {"help", 0, 0, 'h'}, 71 {NULL,0,0,0}, 72}; 73#else 74#if HAVE_GETOPT 75extern char *optarg; 76extern int optind, opterr, optopt; 77#endif 78#endif 79 80static void 81usage (char *program, int error) 82{ 83 FILE *file = error ? stderr : stdout; 84#if HAVE_GETOPT_LONG 85 fprintf (file, _("usage: %s [-savbVh] [-f FORMAT] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n"), 86 program); 87#else 88 fprintf (file, _("usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n"), 89 program); 90#endif 91 fprintf (file, _("List best font matching [pattern]\n")); 92 fprintf (file, "\n"); 93#if HAVE_GETOPT_LONG 94 fprintf (file, _(" -s, --sort display sorted list of matches\n")); 95 fprintf (file, _(" -a, --all display unpruned sorted list of matches\n")); 96 fprintf (file, _(" -v, --verbose display entire font pattern verbosely\n")); 97 fprintf (file, _(" -b, --brief display entire font pattern briefly\n")); 98 fprintf (file, _(" -f, --format=FORMAT use the given output format\n")); 99 fprintf (file, _(" -V, --version display font config version and exit\n")); 100 fprintf (file, _(" -h, --help display this help and exit\n")); 101#else 102 fprintf (file, _(" -s, (sort) display sorted list of matches\n")); 103 fprintf (file, _(" -a (all) display unpruned sorted list of matches\n")); 104 fprintf (file, _(" -v (verbose) display entire font pattern verbosely\n")); 105 fprintf (file, _(" -b (brief) display entire font pattern briefly\n")); 106 fprintf (file, _(" -f FORMAT (format) use the given output format\n")); 107 fprintf (file, _(" -V (version) display font config version and exit\n")); 108 fprintf (file, _(" -h (help) display this help and exit\n")); 109#endif 110 exit (error); 111} 112 113int 114main (int argc, char **argv) 115{ 116 int verbose = 0; 117 int brief = 0; 118 int sort = 0, all = 0; 119 const FcChar8 *format = NULL; 120 const FcChar8 *format_optarg = NULL; 121 int i; 122 FcObjectSet *os = 0; 123 FcFontSet *fs; 124 FcPattern *pat; 125 FcResult result; 126#if HAVE_GETOPT_LONG || HAVE_GETOPT 127 int c; 128 129 setlocale (LC_ALL, ""); 130#if HAVE_GETOPT_LONG 131 while ((c = getopt_long (argc, argv, "asvbf:Vh", longopts, NULL)) != -1) 132#else 133 while ((c = getopt (argc, argv, "asvbf:Vh")) != -1) 134#endif 135 { 136 switch (c) { 137 case 'a': 138 all = 1; 139 break; 140 case 's': 141 sort = 1; 142 break; 143 case 'v': 144 verbose = 1; 145 break; 146 case 'b': 147 brief = 1; 148 break; 149 case 'f': 150 format = format_optarg = (FcChar8 *) strdup (optarg); 151 break; 152 case 'V': 153 fprintf (stderr, "fontconfig version %d.%d.%d\n", 154 FC_MAJOR, FC_MINOR, FC_REVISION); 155 exit (0); 156 case 'h': 157 usage (argv[0], 0); 158 default: 159 usage (argv[0], 1); 160 } 161 } 162 i = optind; 163#else 164 i = 1; 165#endif 166 167 if (argv[i]) 168 { 169 pat = FcNameParse ((FcChar8 *) argv[i]); 170 if (!pat) 171 { 172 fprintf (stderr, _("Unable to parse the pattern\n")); 173 return 1; 174 } 175 while (argv[++i]) 176 { 177 if (!os) 178 os = FcObjectSetCreate (); 179 FcObjectSetAdd (os, argv[i]); 180 } 181 } 182 else 183 pat = FcPatternCreate (); 184 185 if (!pat) 186 return 1; 187 188 FcConfigSubstitute (0, pat, FcMatchPattern); 189 FcDefaultSubstitute (pat); 190 191 fs = FcFontSetCreate (); 192 193 if (sort || all) 194 { 195 FcFontSet *font_patterns; 196 int j; 197 font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); 198 199 if (!font_patterns || font_patterns->nfont == 0) 200 { 201 fprintf (stderr, _("No fonts installed on the system\n")); 202 return 1; 203 } 204 for (j = 0; j < font_patterns->nfont; j++) 205 { 206 FcPattern *font_pattern; 207 208 font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); 209 if (font_pattern) 210 FcFontSetAdd (fs, font_pattern); 211 } 212 213 FcFontSetSortDestroy (font_patterns); 214 } 215 else 216 { 217 FcPattern *match; 218 match = FcFontMatch (0, pat, &result); 219 if (match) 220 FcFontSetAdd (fs, match); 221 } 222 FcPatternDestroy (pat); 223 224 if (!format) 225 { 226 if (os) 227 format = (const FcChar8 *) "%{=unparse}\n"; 228 else 229 format = (const FcChar8 *) "%{=fcmatch}\n"; 230 } 231 232 if (fs) 233 { 234 int j; 235 236 for (j = 0; j < fs->nfont; j++) 237 { 238 FcPattern *font; 239 240 font = FcPatternFilter (fs->fonts[j], os); 241 242 if (verbose || brief) 243 { 244 if (brief) 245 { 246 FcPatternDel (font, FC_CHARSET); 247 FcPatternDel (font, FC_LANG); 248 } 249 FcPatternPrint (font); 250 } 251 else 252 { 253 FcChar8 *s; 254 255 s = FcPatternFormat (font, format); 256 if (s) 257 { 258 printf ("%s", s); 259 FcStrFree (s); 260 } 261 } 262 263 FcPatternDestroy (font); 264 } 265 FcFontSetDestroy (fs); 266 } 267 268 if (os) 269 FcObjectSetDestroy (os); 270 271 FcFini (); 272 273 if (format_optarg) { 274 free ((void*)format_optarg); 275 format_optarg = NULL; 276 } 277 278 return 0; 279} 280