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