fontlist.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. /* This file is part of the GNU plotutils package. Copyright (C) 1995,
  2. 1996, 1997, 1998, 1999, 2000, 2005, 2008, 2009, Free Software
  3. Foundation, Inc.
  4. The GNU plotutils package is free software. You may redistribute it
  5. and/or modify it under the terms of the GNU General Public License as
  6. published by the Free Software foundation; either version 2, or (at your
  7. option) any later version.
  8. The GNU plotutils package is distributed in the hope that it will be
  9. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. General Public License for more details.
  12. You should have received a copy of the GNU General Public License along
  13. with the GNU plotutils package; see the file COPYING. If not, write to
  14. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  15. Boston, MA 02110-1301, USA. */
  16. /* This file contains the display_fonts and list_fonts routines, which are
  17. used in user-level executables that are linked with libplot. (Their
  18. output is device-specific.) These functions are declared in fontlist.h.
  19. Currently, they get information about font names by invoking
  20. undocumented members of the libplot API, which return pointers to
  21. internal library data structures. These undocumented functions are
  22. _pl_get_hershey_font_info, _pl_get_ps_font_info, _pl_get_pcl_font_info,
  23. and _pl_get_stick_font_info. */
  24. #include "sys-defines.h"
  25. #include "libcommon.h"
  26. #include "plot.h"
  27. #include "fontlist.h"
  28. /* for use in printing font names in two columns; assumption is that all
  29. font name strings have lengths in range 0..MAX_FONTNAME_LEN inclusive
  30. (not counting final null) */
  31. #define MAX_FONTNAME_LEN 36
  32. static char spaces[MAX_FONTNAME_LEN+1] = " ";
  33. /* The definitions of these structures are taken from ../libplot/extern.h.
  34. IF THOSE STRUCTURES CHANGE, THESE SHOULD TOO.
  35. Font information is stored in ../libplot/g_fontdb.c, and we'll retrieve
  36. pointers to it by using the undocumented libplot functions. */
  37. struct plHersheyFontInfoStruct
  38. {
  39. const char *name; /* font name */
  40. const char *othername; /* an alias (for backward compatibility) */
  41. const char *orig_name; /* Allen Hershey's original name for it */
  42. short chars[256]; /* array of vector glyphs */
  43. int typeface_index; /* default typeface for the font */
  44. int font_index; /* which font within typeface this is */
  45. bool obliquing; /* whether to apply obliquing */
  46. bool iso8859_1; /* whether font encoding is iso8859-1 */
  47. bool visible; /* whether font is visible, i.e. not internal */
  48. };
  49. struct plPSFontInfoStruct
  50. {
  51. const char *ps_name; /* the postscript font name */
  52. const char *ps_name_alt; /* alternative PS font name, if non-NULL */
  53. const char *ps_name_alt2; /* 2nd alternative PS font name, if non-NULL */
  54. const char *x_name; /* the X Windows font name */
  55. const char *x_name_alt; /* alternative X Windows font name */
  56. const char *x_name_alt2; /* 2nd alternative X Windows font name */
  57. const char *x_name_alt3; /* 3rd alternative X Windows font name */
  58. const char *css_family; /* CSS font family */
  59. const char *css_generic_family; /* CSS generic font family */
  60. const char *css_style; /* CSS font style */
  61. const char *css_weight; /* CSS font weight */
  62. const char *css_stretch; /* CSS font stretch */
  63. const char *css_panose; /* CSS font Panose */
  64. int pcl_typeface; /* the PCL typeface number */
  65. int hpgl_spacing; /* 0=fixed width, 1=variable */
  66. int hpgl_posture; /* 0=upright, 1=italic, etc. */
  67. int hpgl_stroke_weight; /* 0=normal, 3=bold, 4=extra bold, etc. */
  68. int hpgl_symbol_set; /* 0=Roman-8, 14=ISO-8859-1, etc. */
  69. int font_ascent; /* the font's ascent (from bounding box) */
  70. int font_descent; /* the font's descent (from bounding box) */
  71. int font_cap_height; /* the font's cap height */
  72. int font_x_height; /* the font's x height */
  73. short width[256]; /* per-character width information */
  74. short offset[256]; /* per-character left edge information */
  75. int typeface_index; /* default typeface for the font */
  76. int font_index; /* which font within typeface this is */
  77. int fig_id; /* Fig's font id */
  78. bool iso8859_1; /* whether font encoding is iso8859-1 */
  79. };
  80. struct plPCLFontInfoStruct
  81. {
  82. const char *ps_name; /* the postscript font name */
  83. const char *ps_name_alt; /* alternative PS font name, if non-NULL */
  84. const char *substitute_ps_name; /* replacement name (for use in a PS file) */
  85. const char *x_name; /* the X Windows font name */
  86. const char *css_family; /* CSS font family */
  87. const char *css_generic_family; /* CSS generic font family */
  88. const char *css_style; /* CSS font style */
  89. const char *css_weight; /* CSS font weight */
  90. const char *css_stretch; /* CSS font stretch */
  91. const char *css_panose; /* CSS font Panose */
  92. int pcl_typeface; /* the PCL typeface number */
  93. int hpgl_spacing; /* 0=fixed width, 1=variable */
  94. int hpgl_posture; /* 0=upright, 1=italic, etc. */
  95. int hpgl_stroke_weight; /* 0=normal, 3=bold, 4=extra bold, etc. */
  96. int hpgl_symbol_set; /* 0=Roman-8, 14=ISO-8859-1, etc. */
  97. int font_ascent; /* the font's ascent (from bounding box) */
  98. int font_descent; /* the font's descent (from bounding box) */
  99. int font_cap_height; /* the font's cap height */
  100. int font_x_height; /* the font's x height */
  101. short width[256]; /* per-character width information */
  102. short offset[256]; /* per-character left edge information */
  103. int typeface_index; /* default typeface for the font */
  104. int font_index; /* which font within typeface this is */
  105. bool iso8859_1; /* whether font encoding is iso8859-1 */
  106. };
  107. struct plStickFontInfoStruct
  108. {
  109. const char *ps_name; /* the postscript font name */
  110. bool basic; /* basic stick font (supp. on all devices)? */
  111. int pcl_typeface; /* the PCL typeface number */
  112. int hpgl_spacing; /* 0=fixed width, 1=variable */
  113. int hpgl_posture; /* 0=upright, 1=italic, etc. */
  114. int hpgl_stroke_weight; /* 0=normal, 3=bold, 4=extra bold, etc. */
  115. int hpgl_symbol_set; /* 0=Roman-8, 14=ISO-8859-1 */
  116. int font_ascent; /* the font's ascent (from bounding box) */
  117. int font_descent; /* the font's descent (from bounding box) */
  118. int raster_width_lower; /* width of abstract raster (lower half) */
  119. int raster_height_lower; /* height of abstract raster (lower half) */
  120. int raster_width_upper; /* width of abstract raster (upper half) */
  121. int raster_height_upper; /* height of abstract raster (upper half) */
  122. int hpgl_charset_lower; /* old HP character set number (lower half) */
  123. int hpgl_charset_upper; /* old HP character set number (upper half) */
  124. int kerning_table_lower; /* number of a kerning table (lower half) */
  125. int kerning_table_upper; /* number of a kerning table (upper half) */
  126. char width[256]; /* per-character width information */
  127. int offset; /* left edge (applies to all chars) */
  128. int typeface_index; /* default typeface for the font */
  129. int font_index; /* which font within typeface this is */
  130. bool obliquing; /* whether to apply obliquing */
  131. bool iso8859_1; /* encoding is iso8859-1? (after reencoding) */
  132. };
  133. /* List of Plotter types we support getting font information from,
  134. NULL-terminated. This list also appears in the program text below. */
  135. #ifdef INCLUDE_PNG_SUPPORT
  136. #ifndef X_DISPLAY_MISSING
  137. static const char *_known_devices[] =
  138. { "X", "png", "pnm", "gif", "svg", "ai", "ps", "cgm", "fig", "pcl", "hpgl", "regis", "tek", "meta", NULL };
  139. #else
  140. static const char *_known_devices[] =
  141. { "png", "pnm", "gif", "svg", "ai", "ps", "cgm", "fig", "pcl", "hpgl", "regis", "tek", "meta", NULL };
  142. #endif
  143. #else /* not INCLUDE_PNG_SUPPORT */
  144. #ifndef X_DISPLAY_MISSING
  145. static const char *_known_devices[] =
  146. { "X", "pnm", "gif", "svg", "ai", "ps", "cgm", "fig", "pcl", "hpgl", "regis", "tek", "meta", NULL };
  147. #else
  148. static const char *_known_devices[] =
  149. { "pnm", "gif", "svg", "ai", "ps", "cgm", "fig", "pcl", "hpgl", "regis", "tek", "meta", NULL };
  150. #endif
  151. #endif /* not INCLUDE_PNG_SUPPORT */
  152. int
  153. display_fonts (const char *output_format, const char *progname)
  154. {
  155. plPlotter *plotter;
  156. plPlotterParams *plotter_params;
  157. int numfonts, numpairs, i, j, k;
  158. bool found = false, odd;
  159. const char **device_ptr = _known_devices;
  160. while (*device_ptr)
  161. if (strcmp (output_format, *device_ptr++) == 0)
  162. {
  163. found = true;
  164. break;
  165. }
  166. if (found == false || strcmp (output_format, "meta") == 0)
  167. {
  168. #ifdef INCLUDE_PNG_SUPPORT
  169. #ifndef X_DISPLAY_MISSING
  170. fprintf (stderr, "\
  171. To list available fonts, type `%s -T \"format\" --help-fonts',\n\
  172. where \"format\" is the output format, and is one of:\n\
  173. X, png, pnm, gif (bitmap formats), or\n\
  174. svg, ps, ai, cgm, fig, pcl, hpgl, regis, tek (vector formats).\n",
  175. progname);
  176. #else /* X_DISPLAY_MISSING */
  177. fprintf (stderr, "\
  178. To list available fonts, type `%s -T \"format\" --help-fonts',\n\
  179. where \"format\" is the output format, and is one of:\n\
  180. png, pnm, gif (bitmap formats), or\n\
  181. svg, ps, ai, cgm, fig, pcl, hpgl, regis, tek (vector formats).\n",
  182. progname);
  183. #endif /* X_DISPLAY_MISSING */
  184. #else /* not INCLUDE_PNG_SUPPORT */
  185. #ifndef X_DISPLAY_MISSING
  186. fprintf (stderr, "\
  187. To list available fonts, type `%s -T \"format\" --help-fonts',\n\
  188. where \"format\" is the output format, and is one of:\n\
  189. X, pnm, or gif (bitmap formats), or\n\
  190. svg, ps, ai, cgm, fig, pcl, hpgl, regis, tek (vector formats).\n",
  191. progname);
  192. #else /* X_DISPLAY_MISSING */
  193. fprintf (stderr, "\
  194. To list available fonts, type `%s -T \"format\" --help-fonts',\n\
  195. where \"format\" is the output format, and is one of:\n\
  196. pnm or gif (bitmap formats), or\n\
  197. svg, ps, ai, cgm, fig, pcl, hpgl, regis, tek (vector formats).\n",
  198. progname);
  199. #endif /* X_DISPLAY_MISSING */
  200. #endif /* not INCLUDE_PNG_SUPPORT */
  201. return 0;
  202. }
  203. plotter_params = pl_newplparams ();
  204. if ((plotter = pl_newpl_r (output_format, NULL, stdout, stderr,
  205. plotter_params)) == NULL)
  206. {
  207. fprintf (stderr,
  208. "%s: no font information on display device \"%s\" is available\n",
  209. progname, output_format);
  210. return 0;
  211. }
  212. if (pl_havecap_r (plotter, "HERSHEY_FONTS"))
  213. {
  214. const struct plHersheyFontInfoStruct *hershey_font_info =
  215. (const struct plHersheyFontInfoStruct *)_pl_get_hershey_font_info (plotter);
  216. int visible_num;
  217. numfonts = 0;
  218. for (i=0; hershey_font_info[i].name; i++)
  219. if (hershey_font_info[i].visible)
  220. numfonts++;
  221. odd = (numfonts % 2 == 1 ? true : false);
  222. numpairs = numfonts / 2;
  223. /* compute j and k: j=0, k=numpairs + (odd ? 1 : 0) in terms of
  224. visibles */
  225. j = 0;
  226. k = 0;
  227. visible_num = -1;
  228. for (i=0; hershey_font_info[i].name; i++)
  229. if (hershey_font_info[i].visible)
  230. {
  231. visible_num++; /* visible_num is index into array of visibles */
  232. if (visible_num == 0)
  233. j = i;
  234. else if (visible_num == numpairs + (odd ? 1 : 0))
  235. k = i;
  236. }
  237. fprintf (stdout,
  238. "Names of supported Hershey vector fonts (case-insensitive):\n");
  239. for (i=0; i < numpairs; i++)
  240. {
  241. int len;
  242. len = strlen (hershey_font_info[j].name);
  243. fprintf (stdout, "\t%s", hershey_font_info[j].name);
  244. spaces[MAX_FONTNAME_LEN - len] = '\0';
  245. fputs (spaces, stdout);
  246. spaces[MAX_FONTNAME_LEN - len] = ' ';
  247. fprintf (stdout, "%s\n", hershey_font_info[k].name);
  248. /* bump both j and k */
  249. do
  250. j++;
  251. while (hershey_font_info[j].visible == false);
  252. if (i < numpairs - 1)
  253. {
  254. do
  255. k++;
  256. while (hershey_font_info[k].visible == false);
  257. }
  258. }
  259. if (odd)
  260. fprintf (stdout, "\t%s\n", hershey_font_info[j].name);
  261. }
  262. if (pl_havecap_r (plotter, "STICK_FONTS"))
  263. {
  264. const struct plStickFontInfoStruct *stick_font_info =
  265. (const struct plStickFontInfoStruct *)_pl_get_stick_font_info (plotter);
  266. int extra_fonts, *goodfonts;
  267. numfonts = 0;
  268. for (i=0; stick_font_info[i].ps_name; i++)
  269. numfonts++;
  270. /* if this Plotter doesn't support extras, skip them */
  271. extra_fonts = pl_havecap_r (plotter, "EXTRA_STICK_FONTS");
  272. goodfonts = (int *)xmalloc (numfonts * sizeof(int));
  273. for (i=0, j=0; stick_font_info[i].ps_name; i++)
  274. {
  275. if (!extra_fonts && stick_font_info[i].basic == false)
  276. continue;
  277. goodfonts[j++] = i;
  278. }
  279. numfonts = j;
  280. odd = (numfonts % 2 == 1 ? true : false);
  281. numpairs = numfonts / 2;
  282. fprintf (stdout,
  283. "Names of supported HP vector fonts (case-insensitive):\n");
  284. for (i=0, j=0, k=numpairs + (odd ? 1 : 0); i < numpairs; i++)
  285. {
  286. int len;
  287. len = strlen (stick_font_info[goodfonts[j]].ps_name);
  288. fprintf (stdout, "\t%s", stick_font_info[goodfonts[j++]].ps_name);
  289. spaces[MAX_FONTNAME_LEN - len] = '\0';
  290. fputs (spaces, stdout);
  291. spaces[MAX_FONTNAME_LEN - len] = ' ';
  292. fprintf (stdout, "%s\n", stick_font_info[goodfonts[k++]].ps_name);
  293. }
  294. if (odd)
  295. fprintf (stdout, "\t%s\n", stick_font_info[goodfonts[j]].ps_name);
  296. free (goodfonts);
  297. }
  298. if (pl_havecap_r (plotter, "PCL_FONTS"))
  299. {
  300. const struct plPCLFontInfoStruct *pcl_font_info =
  301. (const struct plPCLFontInfoStruct *)_pl_get_pcl_font_info (plotter);
  302. numfonts = 0;
  303. for (i=0; pcl_font_info[i].ps_name; i++)
  304. numfonts++;
  305. odd = (numfonts % 2 == 1 ? true : false);
  306. numpairs = numfonts / 2;
  307. fprintf (stdout,
  308. "Names of supported PCL fonts (case-insensitive):\n");
  309. for (i=0, j=0, k=numpairs + (odd ? 1 : 0); i < numpairs; i++)
  310. {
  311. int len;
  312. len = strlen (pcl_font_info[j].ps_name);
  313. fprintf (stdout, "\t%s", pcl_font_info[j++].ps_name);
  314. spaces[MAX_FONTNAME_LEN - len] = '\0';
  315. fputs (spaces, stdout);
  316. spaces[MAX_FONTNAME_LEN - len] = ' ';
  317. fprintf (stdout, "%s\n", pcl_font_info[k++].ps_name);
  318. }
  319. if (odd)
  320. fprintf (stdout, "\t%s\n", pcl_font_info[j].ps_name);
  321. }
  322. if (pl_havecap_r (plotter, "PS_FONTS"))
  323. {
  324. const struct plPSFontInfoStruct *ps_font_info =
  325. (const struct plPSFontInfoStruct *)_pl_get_ps_font_info (plotter);
  326. numfonts = 0;
  327. for (i=0; ps_font_info[i].ps_name; i++)
  328. numfonts++;
  329. odd = (numfonts % 2 == 1 ? true : false);
  330. numpairs = numfonts / 2;
  331. fprintf (stdout,
  332. "Names of supported Postscript fonts (case-insensitive):\n");
  333. for (i=0, j=0, k=numpairs + (odd ? 1 : 0); i < numpairs; i++)
  334. {
  335. int len;
  336. len = strlen (ps_font_info[j].ps_name);
  337. fprintf (stdout, "\t%s", ps_font_info[j++].ps_name);
  338. spaces[MAX_FONTNAME_LEN - len] = '\0';
  339. fputs (spaces, stdout);
  340. spaces[MAX_FONTNAME_LEN - len] = ' ';
  341. fprintf (stdout, "%s\n", ps_font_info[k++].ps_name);
  342. }
  343. if (odd)
  344. fprintf (stdout, "\t%s\n", ps_font_info[j].ps_name);
  345. }
  346. if (strcmp (output_format, "X") == 0)
  347. {
  348. fprintf (stdout,
  349. "Most core X Window System fonts, such as charter-medium-r-normal,\n");
  350. fprintf (stdout,
  351. "can also be used.\n");
  352. }
  353. return 1;
  354. }
  355. /* Write font names to standard output, in a line-by-line rather than a
  356. tabular form. */
  357. int
  358. list_fonts (const char *output_format, const char *progname)
  359. {
  360. plPlotter *plotter;
  361. plPlotterParams *plotter_params;
  362. bool found = false;
  363. int i;
  364. const char **device_ptr = _known_devices;
  365. while (*device_ptr)
  366. if (strcmp (output_format, *device_ptr++) == 0)
  367. {
  368. found = true;
  369. break;
  370. }
  371. if (found == false)
  372. {
  373. fprintf (stderr,
  374. "%s: no font information on display device \"%s\" is available\n",
  375. progname, output_format);
  376. return 0;
  377. }
  378. plotter_params = pl_newplparams ();
  379. if ((plotter = pl_newpl_r (output_format, NULL, stdout, stderr,
  380. plotter_params)) == NULL)
  381. {
  382. fprintf (stderr,
  383. "%s: no font information on display device \"%s\" is available\n",
  384. progname, output_format);
  385. return 0;
  386. }
  387. if (pl_havecap_r (plotter, "HERSHEY_FONTS"))
  388. {
  389. const struct plHersheyFontInfoStruct *hershey_font_info =
  390. (const struct plHersheyFontInfoStruct *)_pl_get_hershey_font_info (plotter);
  391. for (i=0; hershey_font_info[i].name; i++)
  392. if (hershey_font_info[i].visible)
  393. fprintf (stdout, "%s\n", hershey_font_info[i].name);
  394. }
  395. if (pl_havecap_r (plotter, "STICK_FONTS"))
  396. {
  397. const struct plStickFontInfoStruct *stick_font_info =
  398. (const struct plStickFontInfoStruct *)_pl_get_stick_font_info (plotter);
  399. int extra_fonts = pl_havecap_r (plotter, "EXTRA_STICK_FONTS");
  400. for (i=0; stick_font_info[i].ps_name; i++)
  401. {
  402. if (!extra_fonts && stick_font_info[i].basic == false)
  403. continue;
  404. fprintf (stdout, "%s\n", stick_font_info[i].ps_name);
  405. }
  406. }
  407. if (pl_havecap_r (plotter, "PCL_FONTS"))
  408. {
  409. const struct plPCLFontInfoStruct *pcl_font_info =
  410. (const struct plPCLFontInfoStruct *)_pl_get_pcl_font_info (plotter);
  411. for (i=0; pcl_font_info[i].ps_name; i++)
  412. fprintf (stdout, "%s\n", pcl_font_info[i].ps_name);
  413. }
  414. if (pl_havecap_r (plotter, "PS_FONTS"))
  415. {
  416. const struct plPSFontInfoStruct *ps_font_info =
  417. (const struct plPSFontInfoStruct *)_pl_get_ps_font_info (plotter);
  418. for (i=0; ps_font_info[i].ps_name; i++)
  419. fprintf (stdout, "%s\n", ps_font_info[i].ps_name);
  420. }
  421. return 1;
  422. }