12c393a42Smrg/* 2a6844aabSmrg * fontconfig/fc-match/fc-match.c 32c393a42Smrg * 42c393a42Smrg * Copyright © 2003 Keith Packard 52c393a42Smrg * 62c393a42Smrg * Permission to use, copy, modify, distribute, and sell this software and its 72c393a42Smrg * documentation for any purpose is hereby granted without fee, provided that 82c393a42Smrg * the above copyright notice appear in all copies and that both that 92c393a42Smrg * copyright notice and this permission notice appear in supporting 10ca08ab68Smrg * documentation, and that the name of the author(s) not be used in 112c393a42Smrg * advertising or publicity pertaining to distribution of the software without 12ca08ab68Smrg * specific, written prior permission. The authors make no 132c393a42Smrg * representations about the suitability of this software for any purpose. It 142c393a42Smrg * is provided "as is" without express or implied warranty. 152c393a42Smrg * 16a6844aabSmrg * THE AUTHOR(S) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 172c393a42Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 18a6844aabSmrg * EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY SPECIAL, INDIRECT OR 192c393a42Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 202c393a42Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 212c393a42Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 222c393a42Smrg * PERFORMANCE OF THIS SOFTWARE. 232c393a42Smrg */ 242c393a42Smrg 252c393a42Smrg#ifdef HAVE_CONFIG_H 262c393a42Smrg#include <config.h> 272c393a42Smrg#else 282c393a42Smrg#ifdef linux 292c393a42Smrg#define HAVE_GETOPT_LONG 1 302c393a42Smrg#endif 312c393a42Smrg#define HAVE_GETOPT 1 322c393a42Smrg#endif 332c393a42Smrg 342c393a42Smrg#include <fontconfig/fontconfig.h> 352c393a42Smrg#include <stdio.h> 362c393a42Smrg#include <stdlib.h> 372c393a42Smrg#include <string.h> 38a32e9e42Smrg#include <locale.h> 39a32e9e42Smrg 40a4e54154Smrg#ifdef HAVE_UNISTD_H 41a4e54154Smrg#include <unistd.h> 42a4e54154Smrg#endif 43a4e54154Smrg 44a32e9e42Smrg#ifdef ENABLE_NLS 45a32e9e42Smrg#include <libintl.h> 46a32e9e42Smrg#define _(x) (dgettext(GETTEXT_PACKAGE, x)) 47a32e9e42Smrg#else 48a32e9e42Smrg#define dgettext(d, s) (s) 49a32e9e42Smrg#define _(x) (x) 50a32e9e42Smrg#endif 512c393a42Smrg 522c393a42Smrg#ifndef HAVE_GETOPT 532c393a42Smrg#define HAVE_GETOPT 0 542c393a42Smrg#endif 552c393a42Smrg#ifndef HAVE_GETOPT_LONG 562c393a42Smrg#define HAVE_GETOPT_LONG 0 572c393a42Smrg#endif 582c393a42Smrg 592c393a42Smrg#if HAVE_GETOPT_LONG 602c393a42Smrg#undef _GNU_SOURCE 612c393a42Smrg#define _GNU_SOURCE 622c393a42Smrg#include <getopt.h> 632c393a42Smrgstatic const struct option longopts[] = { 642c393a42Smrg {"sort", 0, 0, 's'}, 652c393a42Smrg {"all", 0, 0, 'a'}, 662c393a42Smrg {"verbose", 0, 0, 'v'}, 67a32e9e42Smrg {"brief", 0, 0, 'b'}, 68a6844aabSmrg {"format", 1, 0, 'f'}, 69a6844aabSmrg {"version", 0, 0, 'V'}, 70a6844aabSmrg {"help", 0, 0, 'h'}, 712c393a42Smrg {NULL,0,0,0}, 722c393a42Smrg}; 732c393a42Smrg#else 742c393a42Smrg#if HAVE_GETOPT 752c393a42Smrgextern char *optarg; 762c393a42Smrgextern int optind, opterr, optopt; 772c393a42Smrg#endif 782c393a42Smrg#endif 792c393a42Smrg 80a6844aabSmrgstatic void 81a6844aabSmrgusage (char *program, int error) 822c393a42Smrg{ 83a6844aabSmrg FILE *file = error ? stderr : stdout; 842c393a42Smrg#if HAVE_GETOPT_LONG 85a32e9e42Smrg fprintf (file, _("usage: %s [-savbVh] [-f FORMAT] [--sort] [--all] [--verbose] [--brief] [--format=FORMAT] [--version] [--help] [pattern] {element...}\n"), 862c393a42Smrg program); 872c393a42Smrg#else 88a32e9e42Smrg fprintf (file, _("usage: %s [-savVh] [-f FORMAT] [pattern] {element...}\n"), 892c393a42Smrg program); 902c393a42Smrg#endif 91a32e9e42Smrg fprintf (file, _("List best font matching [pattern]\n")); 92a6844aabSmrg fprintf (file, "\n"); 932c393a42Smrg#if HAVE_GETOPT_LONG 94a32e9e42Smrg fprintf (file, _(" -s, --sort display sorted list of matches\n")); 95a32e9e42Smrg fprintf (file, _(" -a, --all display unpruned sorted list of matches\n")); 96a32e9e42Smrg fprintf (file, _(" -v, --verbose display entire font pattern verbosely\n")); 97a32e9e42Smrg fprintf (file, _(" -b, --brief display entire font pattern briefly\n")); 98a32e9e42Smrg fprintf (file, _(" -f, --format=FORMAT use the given output format\n")); 99a32e9e42Smrg fprintf (file, _(" -V, --version display font config version and exit\n")); 100a32e9e42Smrg fprintf (file, _(" -h, --help display this help and exit\n")); 1012c393a42Smrg#else 102a32e9e42Smrg fprintf (file, _(" -s, (sort) display sorted list of matches\n")); 103a32e9e42Smrg fprintf (file, _(" -a (all) display unpruned sorted list of matches\n")); 104a32e9e42Smrg fprintf (file, _(" -v (verbose) display entire font pattern verbosely\n")); 105a32e9e42Smrg fprintf (file, _(" -b (brief) display entire font pattern briefly\n")); 106a32e9e42Smrg fprintf (file, _(" -f FORMAT (format) use the given output format\n")); 107a32e9e42Smrg fprintf (file, _(" -V (version) display font config version and exit\n")); 108a32e9e42Smrg fprintf (file, _(" -h (help) display this help and exit\n")); 1092c393a42Smrg#endif 110a6844aabSmrg exit (error); 1112c393a42Smrg} 1122c393a42Smrg 1132c393a42Smrgint 1142c393a42Smrgmain (int argc, char **argv) 1152c393a42Smrg{ 116ca08ab68Smrg int verbose = 0; 117a32e9e42Smrg int brief = 0; 118ca08ab68Smrg int sort = 0, all = 0; 119ca08ab68Smrg const FcChar8 *format = NULL; 120a4e54154Smrg const FcChar8 *format_optarg = NULL; 121ca08ab68Smrg int i; 122ca08ab68Smrg FcObjectSet *os = 0; 123ca08ab68Smrg FcFontSet *fs; 124ca08ab68Smrg FcPattern *pat; 125ca08ab68Smrg FcResult result; 1262c393a42Smrg#if HAVE_GETOPT_LONG || HAVE_GETOPT 127ca08ab68Smrg int c; 1282c393a42Smrg 129a32e9e42Smrg setlocale (LC_ALL, ""); 1302c393a42Smrg#if HAVE_GETOPT_LONG 131a32e9e42Smrg while ((c = getopt_long (argc, argv, "asvbf:Vh", longopts, NULL)) != -1) 1322c393a42Smrg#else 133a32e9e42Smrg while ((c = getopt (argc, argv, "asvbf:Vh")) != -1) 1342c393a42Smrg#endif 1352c393a42Smrg { 1362c393a42Smrg switch (c) { 1372c393a42Smrg case 'a': 1382c393a42Smrg all = 1; 1392c393a42Smrg break; 1402c393a42Smrg case 's': 1412c393a42Smrg sort = 1; 1422c393a42Smrg break; 143a6844aabSmrg case 'v': 144a6844aabSmrg verbose = 1; 145a6844aabSmrg break; 146a32e9e42Smrg case 'b': 147a32e9e42Smrg brief = 1; 148a32e9e42Smrg break; 149a6844aabSmrg case 'f': 150a4e54154Smrg format = format_optarg = (FcChar8 *) strdup (optarg); 151a6844aabSmrg break; 1522c393a42Smrg case 'V': 1532c393a42Smrg fprintf (stderr, "fontconfig version %d.%d.%d\n", 1542c393a42Smrg FC_MAJOR, FC_MINOR, FC_REVISION); 1552c393a42Smrg exit (0); 156a6844aabSmrg case 'h': 157a6844aabSmrg usage (argv[0], 0); 1582c393a42Smrg default: 159a6844aabSmrg usage (argv[0], 1); 1602c393a42Smrg } 1612c393a42Smrg } 1622c393a42Smrg i = optind; 1632c393a42Smrg#else 1642c393a42Smrg i = 1; 1652c393a42Smrg#endif 1662c393a42Smrg 1672c393a42Smrg if (argv[i]) 168a6844aabSmrg { 1692c393a42Smrg pat = FcNameParse ((FcChar8 *) argv[i]); 1706fc018e4Smrg if (!pat) 1716fc018e4Smrg { 172a32e9e42Smrg fprintf (stderr, _("Unable to parse the pattern\n")); 1736fc018e4Smrg return 1; 1746fc018e4Smrg } 175a6844aabSmrg while (argv[++i]) 176a6844aabSmrg { 177a6844aabSmrg if (!os) 178a6844aabSmrg os = FcObjectSetCreate (); 179a6844aabSmrg FcObjectSetAdd (os, argv[i]); 180a6844aabSmrg } 181a6844aabSmrg } 1822c393a42Smrg else 1832c393a42Smrg pat = FcPatternCreate (); 1842c393a42Smrg 1852c393a42Smrg if (!pat) 1862c393a42Smrg return 1; 1872c393a42Smrg 1882c393a42Smrg FcConfigSubstitute (0, pat, FcMatchPattern); 1892c393a42Smrg FcDefaultSubstitute (pat); 1902c393a42Smrg 1912c393a42Smrg fs = FcFontSetCreate (); 1922c393a42Smrg 1932c393a42Smrg if (sort || all) 1942c393a42Smrg { 1952c393a42Smrg FcFontSet *font_patterns; 1962c393a42Smrg int j; 1972c393a42Smrg font_patterns = FcFontSort (0, pat, all ? FcFalse : FcTrue, 0, &result); 1982c393a42Smrg 199ca08ab68Smrg if (!font_patterns || font_patterns->nfont == 0) 200ca08ab68Smrg { 201a32e9e42Smrg fprintf (stderr, _("No fonts installed on the system\n")); 202ca08ab68Smrg return 1; 203ca08ab68Smrg } 2042c393a42Smrg for (j = 0; j < font_patterns->nfont; j++) 2052c393a42Smrg { 2062c393a42Smrg FcPattern *font_pattern; 2072c393a42Smrg 2082c393a42Smrg font_pattern = FcFontRenderPrepare (NULL, pat, font_patterns->fonts[j]); 2092c393a42Smrg if (font_pattern) 2102c393a42Smrg FcFontSetAdd (fs, font_pattern); 2112c393a42Smrg } 2122c393a42Smrg 2132c393a42Smrg FcFontSetSortDestroy (font_patterns); 2142c393a42Smrg } 2152c393a42Smrg else 2162c393a42Smrg { 2172c393a42Smrg FcPattern *match; 2182c393a42Smrg match = FcFontMatch (0, pat, &result); 2192c393a42Smrg if (match) 2202c393a42Smrg FcFontSetAdd (fs, match); 2212c393a42Smrg } 2222c393a42Smrg FcPatternDestroy (pat); 2232c393a42Smrg 224ca08ab68Smrg if (!format) 225ca08ab68Smrg { 226ca08ab68Smrg if (os) 227ca08ab68Smrg format = (const FcChar8 *) "%{=unparse}\n"; 228ca08ab68Smrg else 229ca08ab68Smrg format = (const FcChar8 *) "%{=fcmatch}\n"; 230ca08ab68Smrg } 231ca08ab68Smrg 2322c393a42Smrg if (fs) 2332c393a42Smrg { 2342c393a42Smrg int j; 2352c393a42Smrg 2362c393a42Smrg for (j = 0; j < fs->nfont; j++) 2372c393a42Smrg { 238a6844aabSmrg FcPattern *font; 239a6844aabSmrg 240a6844aabSmrg font = FcPatternFilter (fs->fonts[j], os); 241a6844aabSmrg 242a32e9e42Smrg if (verbose || brief) 2432c393a42Smrg { 244a32e9e42Smrg if (brief) 245a32e9e42Smrg { 246a32e9e42Smrg FcPatternDel (font, FC_CHARSET); 247a32e9e42Smrg FcPatternDel (font, FC_LANG); 248a32e9e42Smrg } 249a6844aabSmrg FcPatternPrint (font); 250a6844aabSmrg } 251ca08ab68Smrg else 252a6844aabSmrg { 253a6844aabSmrg FcChar8 *s; 254a6844aabSmrg 255a6844aabSmrg s = FcPatternFormat (font, format); 256a6844aabSmrg if (s) 257a6844aabSmrg { 258a6844aabSmrg printf ("%s", s); 259ca08ab68Smrg FcStrFree (s); 260a6844aabSmrg } 261a6844aabSmrg } 262a6844aabSmrg 263a6844aabSmrg FcPatternDestroy (font); 2642c393a42Smrg } 2652c393a42Smrg FcFontSetDestroy (fs); 2662c393a42Smrg } 267a6844aabSmrg 268a6844aabSmrg if (os) 269a6844aabSmrg FcObjectSetDestroy (os); 270a6844aabSmrg 2712c393a42Smrg FcFini (); 272a6844aabSmrg 273a4e54154Smrg if (format_optarg) { 274a4e54154Smrg free ((void*)format_optarg); 275a4e54154Smrg format_optarg = NULL; 276a4e54154Smrg } 277a4e54154Smrg 2782c393a42Smrg return 0; 2792c393a42Smrg} 280