GRASS GIS 7 Programmer's Manual  7.5.svn(2018)-r73103
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
psdriver/graph_set.c
Go to the documentation of this file.
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 
13 #include <string.h>
14 #include <stdlib.h>
15 #include <stdarg.h>
16 #include <time.h>
17 #include <math.h>
18 
19 #include <grass/gis.h>
20 #include <grass/glocale.h>
21 #include "psdriver.h"
22 
23 #define DATE_FORMAT "%c"
24 
25 struct ps_state ps;
26 
27 static const char *file_name;
28 
29 static double width, height;
30 static int landscape;
31 
32 struct paper
33 {
34  const char *name;
35  double width, height;
36  double left, right, bot, top;
37 };
38 
39 static const struct paper papers[] = {
40  /* name width height left right bottom top */
41  {"a4", 8.268, 11.693, 0.5, 0.5, 1.0, 1.0},
42  {"a3", 11.693, 16.535, 0.5, 0.5, 1.0, 1.0},
43  {"a2", 16.54, 23.39, 1.0, 1.0, 1.0, 1.0},
44  {"a1", 23.39, 33.07, 1.0, 1.0, 1.0, 1.0},
45  {"a0", 33.07, 46.77, 1.0, 1.0, 1.0, 1.0},
46  {"us-legal", 8.5, 14.0, 1.0, 1.0, 1.0, 1.0},
47  {"us-letter", 8.5, 11.0, 1.0, 1.0, 1.0, 1.0},
48  {"us-tabloid", 11.0, 17.0, 1.0, 1.0, 1.0, 1.0},
49  {NULL, 0, 0, 0, 0, 0, 0}
50 };
51 
52 static void write_prolog(void)
53 {
54  char prolog_file[GPATH_MAX];
55  char date_str[256];
56  FILE *prolog_fp;
57  time_t t = time(NULL);
58  struct tm *tm = localtime(&t);
59 
60  strftime(date_str, sizeof(date_str), DATE_FORMAT, tm);
61 
62  sprintf(prolog_file, "%s/etc/psdriver.ps", G_gisbase());
63 
64  prolog_fp = fopen(prolog_file, "r");
65  if (!prolog_fp)
66  G_fatal_error("Unable to open prolog file");
67 
68  if (ps.encapsulated)
69  output("%%!PS-Adobe-3.0 EPSF-3.0\n");
70  else
71  output("%%!PS-Adobe-3.0\n");
72 
73  output("%%%%LanguageLevel: %d\n", 3);
74  output("%%%%Creator: GRASS PS Driver\n");
75  output("%%%%Title: %s\n", file_name);
76  output("%%%%For: %s\n", G_whoami());
77  output("%%%%Orientation: %s\n", landscape ? "Landscape" : "Portrait");
78  output("%%%%BoundingBox: %d %d %d %d\n",
79  (int)floor(ps.left), (int)floor(ps.bot),
80  (int)ceil(ps.right), (int)ceil(ps.top));
81  output("%%%%CreationDate: %s\n", date_str);
82  output("%%%%EndComments\n");
83 
84  output("%%%%BeginProlog\n");
85  while (!feof(prolog_fp)) {
86  char buf[256];
87 
88  if (!fgets(buf, sizeof(buf), prolog_fp))
89  break;
90 
91  fputs(buf, ps.outfp);
92  }
93  output("%%%%EndProlog\n");
94 
95  fclose(prolog_fp);
96 }
97 
98 void write_setup(void)
99 {
100  output("%%%%BeginSetup\n");
101 
102  output("%.1f %.1f translate\n", ps.left, ps.bot);
103 
104  if (landscape)
105  output("90 rotate 0 1 -1 scale\n");
106  else
107  output("0 %.1f translate 1 -1 scale\n", height);
108 
109  output("%.1f %.1f BEGIN\n", width, height);
110 
111  output("%%%%EndSetup\n");
112  output("%%%%Page: 1 1\n");
113 }
114 
115 static double in2pt(double x)
116 {
117  return x * 72;
118 }
119 
120 static void swap(double *x, double *y)
121 {
122  double tmp = *x;
123 
124  *x = *y;
125  *y = tmp;
126 }
127 
128 static void get_paper(void)
129 {
130  const char *name = getenv("GRASS_RENDER_PS_PAPER");
131  const struct paper *paper;
132  int i;
133 
134  width = screen_width;
135  height = screen_height;
136 
137  ps.left = 0;
138  ps.right = width;
139  ps.bot = 0;
140  ps.top = height;
141 
142  if (landscape)
143  swap(&ps.right, &ps.top);
144 
145  if (!name)
146  return;
147 
148  for (i = 0;; i++) {
149  paper = &papers[i];
150 
151  if (!paper->name)
152  return;
153 
154  if (G_strcasecmp(name, paper->name) == 0)
155  break;
156  }
157 
158  ps.left = in2pt(paper->left);
159  ps.right = in2pt(paper->width) - in2pt(paper->right);
160  ps.bot = in2pt(paper->bot);
161  ps.top = in2pt(paper->height) - in2pt(paper->top);
162 
163  width = ps.right - ps.left;
164  height = in2pt(paper->height) - in2pt(paper->top) - in2pt(paper->bot);
165 
166  if (landscape)
167  swap(&width, &height);
168 
169  ps.right = ps.left + width;
170  ps.bot = ps.top + height;
171 }
172 
173 int PS_Graph_set(void)
174 {
175  const char *p;
176 
177  G_gisinit("PS driver");
178 
179  p = getenv("GRASS_RENDER_FILE");
180  if (!p || strlen(p) == 0)
181  p = FILE_NAME;
182 
183  file_name = p;
184  p = file_name + strlen(file_name) - 4;
185  ps.encapsulated = (G_strcasecmp(p, ".eps") == 0);
186 
187  p = getenv("GRASS_RENDER_TRUECOLOR");
188  ps.true_color = p && strcmp(p, "TRUE") == 0;
189 
190  p = getenv("GRASS_RENDER_PS_LANDSCAPE");
191  landscape = p && strcmp(p, "TRUE") == 0;
192 
193  p = getenv("GRASS_RENDER_PS_HEADER");
194  ps.no_header = p && strcmp(p, "FALSE") == 0;
195 
196  p = getenv("GRASS_RENDER_PS_TRAILER");
197  ps.no_trailer = p && strcmp(p, "FALSE") == 0;
198 
199  G_verbose_message(_("ps: truecolor status %s"),
200  ps.true_color ? _("enabled") : _("disabled"));
201 
202  get_paper();
203 
204  ps.outfp = fopen(file_name, ps.no_header ? "a" : "w");
205 
206  if (!ps.outfp)
207  G_fatal_error("Unable to open output file: %s", file_name);
208 
209  if (!ps.no_header) {
210  write_prolog();
211  write_setup();
212  }
213 
214  G_verbose_message(_("ps: collecting to file '%s'"), file_name);
215  G_verbose_message(_("ps: image size %dx%d"),
217 
218  fflush(ps.outfp);
219 
220  return 0;
221 }
222 
223 /*!
224  \brief Get render file
225 
226  \return file name
227 */
228 const char *PS_Graph_get_file(void)
229 {
230  return file_name;
231 }
232 
233 void output(const char *fmt, ...)
234 {
235  va_list va;
236 
237  va_start(va, fmt);
238  vfprintf(ps.outfp, fmt, va);
239  va_end(va);
240 }
int G_strcasecmp(const char *x, const char *y)
String compare ignoring case (upper or lower)
Definition: strings.c:46
int PS_Graph_set(void)
const char * PS_Graph_get_file(void)
Get render file.
double left
Definition: psdriver.h:17
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
Definition: gis/error.c:109
struct ps_state ps
#define DATE_FORMAT
int screen_width
Definition: driver/init.c:29
int screen_height
Definition: driver/init.c:30
FILE * outfp
Definition: psdriver.h:13
#define NULL
Definition: ccmath.h:32
#define x
struct tm * localtime()
double right
Definition: psdriver.h:17
const char * G_whoami(void)
Gets user&#39;s name.
Definition: gis/whoami.c:35
void G_fatal_error(const char *msg,...)
Print a fatal error message to stderr.
Definition: gis/error.c:160
double t
Definition: r_raster.c:39
int true_color
Definition: psdriver.h:14
int encapsulated
Definition: psdriver.h:15
void write_setup(void)
#define G_gisinit(pgm)
Definition: gis.h:44
fclose(fd)
#define GPATH_MAX
Definition: gis.h:151
void output(const char *fmt,...)
#define FILE_NAME
Definition: htmlmap.h:9
double top
Definition: psdriver.h:17
int no_trailer
Definition: psdriver.h:16
#define _(str)
Definition: glocale.h:13
int no_header
Definition: psdriver.h:16
const char * name
Definition: named_colr.c:7
char * getenv()
double bot
Definition: psdriver.h:17
const char * G_gisbase(void)
Get full path name of the top level module directory.
Definition: gisbase.c:41