123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- * Start up graphics processing. Anything that needs to be assigned, set up,
- * started-up, or otherwise initialized happens here. This is called only at
- * the startup of the graphics driver.
- *
- * The external variables define the pixle limits of the graphics surface. The
- * coordinate system used by the applications programs has the (0,0) origin
- * in the upper left-hand corner. Hence,
- * screen_left < screen_right
- * screen_top < screen_bottom
- */
- #include <string.h>
- #include <stdlib.h>
- #include <stdarg.h>
- #include <time.h>
- #include <math.h>
- #include <unistd.h>
- #include <grass/gis.h>
- #include <grass/glocale.h>
- #include "psdriver.h"
- #define DATE_FORMAT "%c"
- struct ps_state ps;
- static double width, height;
- static int landscape;
- struct paper
- {
- const char *name;
- double width, height;
- double left, right, bot, top;
- };
- static const struct paper papers[] = {
- /* name width height left right bottom top */
- {"a4", 8.268, 11.693, 0.5, 0.5, 1.0, 1.0},
- {"a3", 11.693, 16.535, 0.5, 0.5, 1.0, 1.0},
- {"a2", 16.54, 23.39, 1.0, 1.0, 1.0, 1.0},
- {"a1", 23.39, 33.07, 1.0, 1.0, 1.0, 1.0},
- {"a0", 33.07, 46.77, 1.0, 1.0, 1.0, 1.0},
- {"us-legal", 8.5, 14.0, 1.0, 1.0, 1.0, 1.0},
- {"us-letter", 8.5, 11.0, 1.0, 1.0, 1.0, 1.0},
- {"us-tabloid", 11.0, 17.0, 1.0, 1.0, 1.0, 1.0},
- {NULL, 0, 0, 0, 0, 0, 0}
- };
- static void write_prolog(void)
- {
- char prolog_file[GPATH_MAX];
- char date_str[256];
- FILE *prolog_fp;
- time_t t = time(NULL);
- struct tm *tm = localtime(&t);
- strftime(date_str, sizeof(date_str), DATE_FORMAT, tm);
- sprintf(prolog_file, "%s/etc/psdriver.ps", G_gisbase());
- prolog_fp = fopen(prolog_file, "r");
- if (!prolog_fp)
- G_fatal_error("Unable to open prolog file");
- if (ps.encapsulated)
- output("%%!PS-Adobe-3.0 EPSF-3.0\n");
- else
- output("%%!PS-Adobe-3.0\n");
- output("%%%%LanguageLevel: %d\n", 3);
- output("%%%%Creator: GRASS PS Driver\n");
- output("%%%%Title: %s\n", ps.outfile);
- output("%%%%For: %s\n", G_whoami());
- output("%%%%Orientation: %s\n", landscape ? "Landscape" : "Portrait");
- output("%%%%BoundingBox: %d %d %d %d\n",
- (int)floor(ps.left), (int)floor(ps.bot),
- (int)ceil(ps.right), (int)ceil(ps.top));
- output("%%%%CreationDate: %s\n", date_str);
- output("%%%%EndComments\n");
- output("%%%%BeginProlog\n");
- while (!feof(prolog_fp)) {
- char buf[256];
- if (!fgets(buf, sizeof(buf), prolog_fp))
- break;
- fputs(buf, ps.tempfp);
- }
- output("%%%%EndProlog\n");
- fclose(prolog_fp);
- }
- void write_setup(void)
- {
- output("%%%%BeginSetup\n");
- output("%.1f %.1f translate\n", ps.left, ps.bot);
- if (landscape)
- output("90 rotate 0 1 -1 scale\n");
- else
- output("0 %.1f translate 1 -1 scale\n", height);
- output("%.1f %.1f BEGIN\n", width, height);
- output("%%%%EndSetup\n");
- output("%%%%Page: 1 1\n");
- }
- static double in2pt(double x)
- {
- return x * 72;
- }
- static void swap(double *x, double *y)
- {
- double tmp = *x;
- *x = *y;
- *y = tmp;
- }
- static void get_paper(void)
- {
- const char *name = getenv("GRASS_RENDER_PS_PAPER");
- const struct paper *paper;
- int i;
- width = screen_width;
- height = screen_height;
- ps.left = 0;
- ps.right = width;
- ps.bot = 0;
- ps.top = height;
- if (landscape)
- swap(&ps.right, &ps.top);
- if (!name)
- return;
- for (i = 0;; i++) {
- paper = &papers[i];
- if (!paper->name)
- return;
- if (G_strcasecmp(name, paper->name) == 0)
- break;
- }
- ps.left = in2pt(paper->left);
- ps.right = in2pt(paper->width) - in2pt(paper->right);
- ps.bot = in2pt(paper->bot);
- ps.top = in2pt(paper->height) - in2pt(paper->top);
- width = ps.right - ps.left;
- height = in2pt(paper->height) - in2pt(paper->top) - in2pt(paper->bot);
- if (landscape)
- swap(&width, &height);
- ps.right = ps.left + width;
- ps.bot = ps.top + height;
- }
- int PS_Graph_set(void)
- {
- const char *p;
- G_gisinit("PS driver");
- p = getenv("GRASS_RENDER_FILE");
- if (!p || strlen(p) == 0)
- p = FILE_NAME;
- ps.outfile = p;
- p = ps.outfile + strlen(ps.outfile) - 4;
- ps.encapsulated = (G_strcasecmp(p, ".eps") == 0);
- p = getenv("GRASS_RENDER_TRUECOLOR");
- ps.true_color = p && strcmp(p, "TRUE") == 0;
- p = getenv("GRASS_RENDER_PS_LANDSCAPE");
- landscape = p && strcmp(p, "TRUE") == 0;
- p = getenv("GRASS_RENDER_PS_HEADER");
- ps.no_header = p && strcmp(p, "FALSE") == 0;
- p = getenv("GRASS_RENDER_PS_TRAILER");
- ps.no_trailer = p && strcmp(p, "FALSE") == 0;
- G_verbose_message(_("ps: truecolor status %s"),
- ps.true_color ? _("enabled") : _("disabled"));
- get_paper();
- ps.tempfile = G_tempfile();
- if (ps.no_header && access(ps.outfile, F_OK) == 0)
- G_rename_file(ps.outfile, ps.tempfile);
- ps.tempfp = fopen(ps.tempfile, ps.no_header ? "a" : "w");
- if (!ps.tempfp)
- G_fatal_error("Unable to open output file: %s", ps.outfile);
- if (!ps.no_header) {
- write_prolog();
- write_setup();
- }
- G_verbose_message(_("ps: collecting to file '%s'"), ps.outfile);
- G_verbose_message(_("ps: image size %dx%d"),
- screen_width, screen_height);
- fflush(ps.tempfp);
- return 0;
- }
- /*!
- \brief Get render file
- \return file name
- */
- const char *PS_Graph_get_file(void)
- {
- return ps.outfile;
- }
- void output(const char *fmt, ...)
- {
- va_list va;
- va_start(va, fmt);
- vfprintf(ps.tempfp, fmt, va);
- va_end(va);
- }
|