hersheydemo.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /* This file is part of the GNU plotutils package.
  2. Copyright (C) 1989--2009, Free Software Foundation, Inc.
  3. The GNU plotutils package is free software. You may redistribute it
  4. and/or modify it under the terms of the GNU General Public License as
  5. published by the Free Software foundation; either version 2, or (at your
  6. option) any later version.
  7. The GNU plotutils package is distributed in the hope that it will be
  8. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with the GNU plotutils package; see the file COPYING. If not, write to
  13. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  14. Boston, MA 02110-1301, USA. */
  15. /* This program, hersheydemo, is a demo program for the Hershey vector
  16. fonts, as implemented in GNU libplot. It outputs a demo page, designed
  17. by Dr. Allen Hershey himself. The page is taken from his 1972 article
  18. "A computer system for scientific typography", published in Computer
  19. Graphics and Image Processing (vol. 1, no. 4, pp. 373-385).
  20. The demo page may be output in any of the vector or bitmap formats that
  21. GNU libplot supports. The output format is specified with the `-T'
  22. option. For instance, do
  23. hersheydemo -TX
  24. to pop up a window on an X Window System display, showing Dr. Hershey's
  25. demo page. Do
  26. hersheydemo -Tps > output.ps
  27. to obtain a Postscript output file, and
  28. hersheydemo -Tps | gv -
  29. to display the file immediately, using Ghostview. Do
  30. hersheydemo -Tsvg > output.svg
  31. to obtain an SVG (Scalable Vector Graphics) file, or
  32. hersheydemo -Tsvg | display
  33. to display it immediately, using the `display' program that is part of
  34. the ImageMagick package. Within a traditional `xterm' terminal emulator
  35. window (though not within any of the more recent terminal emulators),
  36. you can do
  37. hersheydemo -Ttek
  38. to display the demo page using the terminal window's Tektronix mode,
  39. which will pop up an auxiliary window.
  40. Additional formats are supported; do `hersheydemo --help' for a list.
  41. In most of the above output formats, you can use the `--pen-color
  42. option' to change then pen color; for instance, you can include
  43. `--pen-color blue' to draw with a blue pen instead of a black pen (the
  44. default). Also, in many of the above output formats you can use the
  45. `--bg-color' option to specify the background color. For instance, you
  46. can include `--bg-color yellow' to obtain a yellow background.
  47. In most output formats, you can use the `--rotation 90' option to
  48. rotate by 90 degrees, etc.
  49. */
  50. #include "sys-defines.h"
  51. #include "libcommon.h"
  52. #include "getopt.h"
  53. #include "plot.h"
  54. #ifdef M_SQRT1_2
  55. #undef M_SQRT1_2
  56. #endif
  57. #define M_SQRT1_2 (0.70710678118654752440) /* 1/sqrt(2) */
  58. #define NUM_DEMO_WORDS 34
  59. struct hershey_word
  60. {
  61. const char *word;
  62. const char *fontname; /* Hershey font name, libplot-style */
  63. double m[6]; /* PS-style transformation matrix */
  64. char just; /* horizontal justification (left/center/right) */
  65. };
  66. /* Dr. Hershey's glyph database includes reduced-size (`indexical') and
  67. small-size (`cartographic') glyphs. Some of the strings on his demo
  68. page used them. By default, libplot does not use the indexical or
  69. cartographic glyphs (though they can be retrieved from the glyph
  70. database, which is incorporated bodily into libplot, if necessary).
  71. Hence we scale by an appropriate factor when rendering the strings that
  72. were originally indexical or cartographic, as the full-sized glyphs in
  73. the database will be used to render them. */
  74. #define CART (9.0/21.0) /* `cartographic' size */
  75. #define INDEXICAL (13.0/21.0) /* `indexical' size */
  76. /* bounding box */
  77. #define LLX -3800.0
  78. #define LLY -3450.0
  79. #define URX 3800.0
  80. #define URY 4150.0
  81. #define BASE_FONTSIZE 220.0
  82. const struct hershey_word demo_word[NUM_DEMO_WORDS] =
  83. {
  84. {"Invitation", "HersheyScript-Bold",
  85. { 1., 0., 0., 1., -3125., 3980. }, 'l' },
  86. {"ECONOMY", "HersheySans",
  87. { 1., 0., 0., 1., -3125., 3340. }, 'l'},
  88. {"CARTOGRAPHY", "HersheySans",
  89. { CART, 0., 0., CART, -3125., 2700. }, 'l'},
  90. {"Gramma", "HersheySerifSymbol",
  91. { 1., 0., 0., 1., -3125., 2060. }, 'l'},
  92. {"\347\322\301\306\311\313\301", "HersheyCyrillic",
  93. { 1., 0., 0., 1., -3125., 1420. }, 'l'},
  94. {"COMMUNICATION", "HersheySans-Bold",
  95. { 1., 0., 0., 1., 0., 3980. }, 'c'},
  96. {"VERSATILITY", "HersheySerif-Italic",
  97. { 1., 0., 0., 1., 0., 3340. }, 'c'},
  98. {"Standardization", "HersheySerif",
  99. { 1., 0., 0., 1., 0., 2700. }, 'c'},
  100. {"Sumbolon", "HersheySerifSymbol",
  101. { INDEXICAL, 0., 0., INDEXICAL, 0., 2060. }, 'c'},
  102. {"\363\354\357\366\356\357\363\364\370", "HersheyCyrillic",
  103. { 1., 0., 0., 1., 0., 1420. }, 'c'},
  104. {"Publication", "HersheyScript-Bold",
  105. { 1., 0., 0., 1., 3125., 3980. }, 'r'},
  106. {"Quality", "HersheyGothicEnglish",
  107. { 1., 0., 0., 1., 3125., 3340. }, 'r'},
  108. {"TYPOGRAPHY", "HersheySans",
  109. { CART, 0., 0., CART, 3125., 2700. }, 'r'},
  110. {"AriJmo\\s-", "HersheySerifSymbol",
  111. { 1., 0., 0., 1., 3125., 2060. }, 'r'},
  112. {"\346\317\316\305\324\311\313\301", "HersheyCyrillic",
  113. { 1., 0., 0., 1., 3125., 1420. }, 'r'},
  114. {"EXTENSION", "HersheySans",
  115. { 17./7., 0., 0., 2./7., 0., 780. }, 'c'},
  116. {"CONDENSATION", "HersheySans",
  117. { 5./7., 0., 0., 17./7., 0., -20. }, 'c'},
  118. {"Rotation", "HersheySans",
  119. { M_SQRT1_2, M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, -2880., -20. }, 'l'},
  120. {"ROTATION", "HersheySans",
  121. { M_SQRT1_2, -M_SQRT1_2, M_SQRT1_2, M_SQRT1_2, 2880., -20. }, 'r'},
  122. {"Syllabary", "HersheySerif",
  123. { 1., 0., 0., 1., -3125., -780. }, 'l'},
  124. {"Art", "HersheyGothicEnglish",
  125. { 1., 0., 0., 1., -3125., -1420. }, 'l'},
  126. {"Meteorology", "HersheySerif-Italic",
  127. { INDEXICAL, 0., 0., INDEXICAL, -3125., -2060.}, 'l'},
  128. {"CHEMISTRY", "HersheySerif",
  129. { 1., 0., 0., 1., -3125., -2700.}, 'l'},
  130. {"Analysis", "HersheySerif-BoldItalic",
  131. { 1., 0., 0., 1., -3125., -3340.}, 'l'},
  132. {"LEXIKON", "HersheySerifSymbol-Bold",
  133. { 1., 0., 0., 1., 0., -780.}, 'c'},
  134. {"\\#J3d71\\#J463b", "HersheySerif",
  135. { 1./.7, 0., 0., 1./.7, 0., -1420.}, 'c'},
  136. {"Wissenschaft", "HersheyGothicGerman",
  137. { 1., 0., 0., 1., 0., -2060.}, 'c'},
  138. {"Electronics", "HersheySerif-Italic",
  139. { 1., 0., 0., 1., 0., -2700.}, 'c'},
  140. {"COMPUTATION", "HersheySerif-Bold",
  141. { 1., 0., 0., 1., 0., -3340.}, 'c'},
  142. {"Alphabet", "HersheySerif",
  143. { 1., 0., 0., 1., 3125., -780.}, 'r'},
  144. {"Music", "HersheyGothicItalian",
  145. { 1., 0., 0., 1., 3125., -1420.}, 'r'},
  146. {"Astronomy", "HersheySerif",
  147. { INDEXICAL, 0., 0., INDEXICAL, 3125., -2060.}, 'r'},
  148. {"MATHEMATICS", "HersheySerif",
  149. { 1., 0., 0., 1., 3125., -2700.}, 'r'},
  150. {"Program", "HersheySerif-BoldItalic",
  151. { 1., 0., 0., 1., 3125., -3340.}, 'r'},
  152. };
  153. const char *progname = "hersheydemo"; /* name of this program */
  154. const char *written = "Written by Robert S. Maier.";
  155. const char *copyright = "Copyright (C) 2009 Free Software Foundation, Inc.";
  156. const char *usage_appendage = "\n";
  157. char *bg_color = NULL; /* bg color */
  158. char *pen_color = NULL; /* pen color */
  159. char *bitmap_size = NULL; /* e.g. 500x500 (for bitmap output formats) */
  160. char *page_size = NULL; /* e.g. a4 (certain vector output formats) */
  161. /* options */
  162. #define ARG_NONE 0
  163. #define ARG_REQUIRED 1
  164. #define ARG_OPTIONAL 2
  165. const char *optstring = "T:";
  166. struct option long_options[] =
  167. {
  168. /* The most important option ("--display-type" is an obsolete variant) */
  169. { "output-format", ARG_REQUIRED, NULL, 'T'},
  170. { "display-type", ARG_REQUIRED, NULL, 'T' << 8 }, /* obsolete */
  171. /* Long options with (mostly) no equivalent short option alias */
  172. { "bg-color", ARG_REQUIRED, NULL, 'q' << 8 },
  173. { "pen-color", ARG_REQUIRED, NULL, 'C' << 8 },
  174. { "rotation", ARG_REQUIRED, NULL, 'r' << 8},
  175. { "bitmap-size", ARG_REQUIRED, NULL, 'B' << 8},
  176. { "page-size", ARG_REQUIRED, NULL, 'P' << 8},
  177. /* Documentation options */
  178. { "version", ARG_NONE, NULL, 'V' << 8 },
  179. { "help", ARG_NONE, NULL, 'h' << 8 },
  180. { NULL, 0, NULL, 0}
  181. };
  182. /* null-terminated list of options, such as obsolete-but-still-maintained
  183. options or undocumented options, which we don't show to the user */
  184. const int hidden_options[] = {(int)('T' << 8), 0 };
  185. int
  186. main (int argc, char *argv[])
  187. {
  188. plPlotter *plotter;
  189. plPlotterParams *plotter_params;
  190. bool show_usage = false; /* show usage message? */
  191. bool show_version = false; /* show version message? */
  192. char *output_format = (char *)"meta"; /* default libplot output format */
  193. int errcnt = 0; /* errors encountered */
  194. int opt_index; /* long option index */
  195. int option; /* option character */
  196. int i;
  197. /* set Plotter parameters */
  198. plotter_params = pl_newplparams ();
  199. while ((option = getopt_long (argc, argv, optstring, long_options, &opt_index)) != EOF)
  200. {
  201. if (option == 0)
  202. option = long_options[opt_index].val;
  203. switch (option)
  204. {
  205. case 'T': /* Output format, ARG REQUIRED */
  206. case 'T' << 8:
  207. output_format = (char *)xmalloc (strlen (optarg) + 1);
  208. strcpy (output_format, optarg);
  209. break;
  210. case 'C' << 8: /* set the pen color, ARG REQUIRED */
  211. pen_color = (char *)xmalloc (strlen (optarg) + 1);
  212. strcpy (pen_color, optarg);
  213. break;
  214. case 'q' << 8: /* set the background color, ARG REQUIRED */
  215. bg_color = (char *)xmalloc (strlen (optarg) + 1);
  216. strcpy (bg_color, optarg);
  217. break;
  218. case 'r' << 8: /* Plot rotation angle, ARG REQUIRED */
  219. pl_setplparam (plotter_params, "ROTATION", (void *)optarg);
  220. break;
  221. case 'B' << 8: /* Bitmap size, ARG REQUIRED */
  222. pl_setplparam (plotter_params, "BITMAPSIZE", (void *)optarg);
  223. break;
  224. case 'P' << 8: /* Page size, ARG REQUIRED */
  225. pl_setplparam (plotter_params, "PAGESIZE", (void *)optarg);
  226. break;
  227. case 'V' << 8: /* Version */
  228. show_version = true;
  229. break;
  230. case 'h' << 8: /* Help */
  231. show_usage = true;
  232. break;
  233. default:
  234. errcnt++;
  235. break;
  236. }
  237. }
  238. if (errcnt > 0)
  239. {
  240. fprintf (stderr, "Try `%s --help' for more information\n", progname);
  241. return EXIT_FAILURE;
  242. }
  243. if (show_version)
  244. {
  245. display_version (progname, written, copyright);
  246. return EXIT_SUCCESS;
  247. }
  248. if (show_usage)
  249. {
  250. display_usage (progname, hidden_options, usage_appendage, 1);
  251. return EXIT_SUCCESS;
  252. }
  253. if (bg_color)
  254. /* select user-specified background color */
  255. pl_setplparam (plotter_params, "BG_COLOR", (void *)bg_color);
  256. if ((plotter = pl_newpl_r (output_format, NULL, stdout, stderr,
  257. plotter_params)) == NULL)
  258. {
  259. fprintf (stderr, "%s: error: the plot device could not be created\n", progname);
  260. return EXIT_FAILURE;
  261. }
  262. /* open the plot device, set up user coordinate system */
  263. pl_openpl_r (plotter);
  264. pl_erase_r (plotter);
  265. pl_fspace_r (plotter, LLX, LLY, URX, URY);
  266. if (pen_color)
  267. pl_pencolorname_r (plotter, pen_color);
  268. /* loop through words, displaying each; and each time, saving and
  269. restoring the graphics state (which includes the current
  270. transformation matrix) */
  271. for (i = 0; i < NUM_DEMO_WORDS; i++)
  272. {
  273. pl_savestate_r (plotter);
  274. pl_fontname_r (plotter, demo_word[i].fontname);
  275. /* insert a PS-style transformation matrix, including both
  276. repositioning and scaling, into the graphics pipeline */
  277. pl_fconcat_r (plotter,
  278. demo_word[i].m[0], demo_word[i].m[1],
  279. demo_word[i].m[2], demo_word[i].m[3],
  280. demo_word[i].m[4], demo_word[i].m[5]);
  281. /* all words have the same font size in user coordinates
  282. (though not necessarily in device coordinates) */
  283. pl_ffontsize_r (plotter, BASE_FONTSIZE);
  284. /* all words have the same location in user coordinates
  285. (though not, obviously, in device coordinates) */
  286. pl_fmove_r (plotter, 0.0, 0.0);
  287. /* each word is drawn as an `alabel' (adjusted label), i.e., text
  288. string with specified horizontal justification and with vertical
  289. justification that is always `c', i.e., which is vertically
  290. centered */
  291. pl_alabel_r (plotter, demo_word[i].just, 'c', demo_word[i].word);
  292. pl_restorestate_r (plotter);
  293. }
  294. /* close and delete Plotter */
  295. pl_closepl_r (plotter);
  296. if (pl_deletepl_r (plotter) < 0)
  297. {
  298. fprintf (stderr, "Couldn't delete Plotter\n");
  299. return EXIT_FAILURE;
  300. }
  301. return EXIT_SUCCESS;
  302. }