hb-fc-list.c 5.5 KB

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