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