graph_set.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. /*
  2. * Start up graphics processing. Anything that needs to be assigned, set up,
  3. * started-up, or otherwise initialized happens here. This is called only at
  4. * the startup of the graphics driver.
  5. *
  6. * The external variables define the pixle limits of the graphics surface. The
  7. * coordinate system used by the applications programs has the (0,0) origin
  8. * in the upper left-hand corner. Hence,
  9. * screen_left < screen_right
  10. * screen_top < screen_bottom
  11. */
  12. #include <string.h>
  13. #include <stdlib.h>
  14. #include <stdarg.h>
  15. #include <time.h>
  16. #include <math.h>
  17. #include <unistd.h>
  18. #include <grass/gis.h>
  19. #include <grass/glocale.h>
  20. #include "psdriver.h"
  21. #define DATE_FORMAT "%c"
  22. struct ps_state ps;
  23. static double width, height;
  24. static int landscape;
  25. struct paper
  26. {
  27. const char *name;
  28. double width, height;
  29. double left, right, bot, top;
  30. };
  31. static const struct paper papers[] = {
  32. /* name width height left right bottom top */
  33. {"a4", 8.268, 11.693, 0.5, 0.5, 1.0, 1.0},
  34. {"a3", 11.693, 16.535, 0.5, 0.5, 1.0, 1.0},
  35. {"a2", 16.54, 23.39, 1.0, 1.0, 1.0, 1.0},
  36. {"a1", 23.39, 33.07, 1.0, 1.0, 1.0, 1.0},
  37. {"a0", 33.07, 46.77, 1.0, 1.0, 1.0, 1.0},
  38. {"us-legal", 8.5, 14.0, 1.0, 1.0, 1.0, 1.0},
  39. {"us-letter", 8.5, 11.0, 1.0, 1.0, 1.0, 1.0},
  40. {"us-tabloid", 11.0, 17.0, 1.0, 1.0, 1.0, 1.0},
  41. {NULL, 0, 0, 0, 0, 0, 0}
  42. };
  43. static void write_prolog(void)
  44. {
  45. char prolog_file[GPATH_MAX];
  46. char date_str[256];
  47. FILE *prolog_fp;
  48. time_t t = time(NULL);
  49. struct tm *tm = localtime(&t);
  50. strftime(date_str, sizeof(date_str), DATE_FORMAT, tm);
  51. sprintf(prolog_file, "%s/etc/psdriver.ps", G_gisbase());
  52. prolog_fp = fopen(prolog_file, "r");
  53. if (!prolog_fp)
  54. G_fatal_error("Unable to open prolog file");
  55. if (ps.encapsulated)
  56. output("%%!PS-Adobe-3.0 EPSF-3.0\n");
  57. else
  58. output("%%!PS-Adobe-3.0\n");
  59. output("%%%%LanguageLevel: %d\n", 3);
  60. output("%%%%Creator: GRASS PS Driver\n");
  61. output("%%%%Title: %s\n", ps.outfile);
  62. output("%%%%For: %s\n", G_whoami());
  63. output("%%%%Orientation: %s\n", landscape ? "Landscape" : "Portrait");
  64. output("%%%%BoundingBox: %d %d %d %d\n",
  65. (int)floor(ps.left), (int)floor(ps.bot),
  66. (int)ceil(ps.right), (int)ceil(ps.top));
  67. output("%%%%CreationDate: %s\n", date_str);
  68. output("%%%%EndComments\n");
  69. output("%%%%BeginProlog\n");
  70. while (!feof(prolog_fp)) {
  71. char buf[256];
  72. if (!fgets(buf, sizeof(buf), prolog_fp))
  73. break;
  74. fputs(buf, ps.tempfp);
  75. }
  76. output("%%%%EndProlog\n");
  77. fclose(prolog_fp);
  78. }
  79. void write_setup(void)
  80. {
  81. output("%%%%BeginSetup\n");
  82. output("%.1f %.1f translate\n", ps.left, ps.bot);
  83. if (landscape)
  84. output("90 rotate 0 1 -1 scale\n");
  85. else
  86. output("0 %.1f translate 1 -1 scale\n", height);
  87. output("%.1f %.1f BEGIN\n", width, height);
  88. output("%%%%EndSetup\n");
  89. output("%%%%Page: 1 1\n");
  90. }
  91. static double in2pt(double x)
  92. {
  93. return x * 72;
  94. }
  95. static void swap(double *x, double *y)
  96. {
  97. double tmp = *x;
  98. *x = *y;
  99. *y = tmp;
  100. }
  101. static void get_paper(void)
  102. {
  103. const char *name = getenv("GRASS_RENDER_PS_PAPER");
  104. const struct paper *paper;
  105. int i;
  106. width = screen_width;
  107. height = screen_height;
  108. ps.left = 0;
  109. ps.right = width;
  110. ps.bot = 0;
  111. ps.top = height;
  112. if (landscape)
  113. swap(&ps.right, &ps.top);
  114. if (!name)
  115. return;
  116. for (i = 0;; i++) {
  117. paper = &papers[i];
  118. if (!paper->name)
  119. return;
  120. if (G_strcasecmp(name, paper->name) == 0)
  121. break;
  122. }
  123. ps.left = in2pt(paper->left);
  124. ps.right = in2pt(paper->width) - in2pt(paper->right);
  125. ps.bot = in2pt(paper->bot);
  126. ps.top = in2pt(paper->height) - in2pt(paper->top);
  127. width = ps.right - ps.left;
  128. height = in2pt(paper->height) - in2pt(paper->top) - in2pt(paper->bot);
  129. if (landscape)
  130. swap(&width, &height);
  131. ps.right = ps.left + width;
  132. ps.bot = ps.top + height;
  133. }
  134. int PS_Graph_set(void)
  135. {
  136. const char *p;
  137. G_gisinit("PS driver");
  138. p = getenv("GRASS_RENDER_FILE");
  139. if (!p || strlen(p) == 0)
  140. p = FILE_NAME;
  141. ps.outfile = p;
  142. p = ps.outfile + strlen(ps.outfile) - 4;
  143. ps.encapsulated = (G_strcasecmp(p, ".eps") == 0);
  144. p = getenv("GRASS_RENDER_TRUECOLOR");
  145. ps.true_color = p && strcmp(p, "TRUE") == 0;
  146. p = getenv("GRASS_RENDER_PS_LANDSCAPE");
  147. landscape = p && strcmp(p, "TRUE") == 0;
  148. p = getenv("GRASS_RENDER_PS_HEADER");
  149. ps.no_header = p && strcmp(p, "FALSE") == 0;
  150. p = getenv("GRASS_RENDER_PS_TRAILER");
  151. ps.no_trailer = p && strcmp(p, "FALSE") == 0;
  152. G_verbose_message(_("ps: truecolor status %s"),
  153. ps.true_color ? _("enabled") : _("disabled"));
  154. get_paper();
  155. ps.tempfile = G_tempfile();
  156. if (ps.no_header && access(ps.outfile, F_OK) == 0)
  157. G_rename_file(ps.outfile, ps.tempfile);
  158. ps.tempfp = fopen(ps.tempfile, ps.no_header ? "a" : "w");
  159. if (!ps.tempfp)
  160. G_fatal_error("Unable to open output file: %s", ps.outfile);
  161. if (!ps.no_header) {
  162. write_prolog();
  163. write_setup();
  164. }
  165. G_verbose_message(_("ps: collecting to file '%s'"), ps.outfile);
  166. G_verbose_message(_("ps: image size %dx%d"),
  167. screen_width, screen_height);
  168. fflush(ps.tempfp);
  169. return 0;
  170. }
  171. /*!
  172. \brief Get render file
  173. \return file name
  174. */
  175. const char *PS_Graph_get_file(void)
  176. {
  177. return ps.outfile;
  178. }
  179. void output(const char *fmt, ...)
  180. {
  181. va_list va;
  182. va_start(va, fmt);
  183. vfprintf(ps.tempfp, fmt, va);
  184. va_end(va);
  185. }