GRASS Programmer's Manual  6.4.2(2012)
psdriver/Graph_set.c
Go to the documentation of this file.
00001 /*
00002  * Start up graphics processing.  Anything that needs to be assigned, set up,
00003  * started-up, or otherwise initialized happens here.  This is called only at
00004  * the startup of the graphics driver.
00005  *
00006  * The external variables define the pixle limits of the graphics surface.  The
00007  * coordinate system used by the applications programs has the (0,0) origin
00008  * in the upper left-hand corner.  Hence,
00009  *    screen_left < screen_right
00010  *    screen_top  < screen_bottom 
00011  */
00012 
00013 #include <string.h>
00014 #include <stdlib.h>
00015 #include <stdarg.h>
00016 #include <time.h>
00017 
00018 #include <grass/gis.h>
00019 #include "psdriver.h"
00020 
00021 #define DATE_FORMAT "%c"
00022 
00023 const char *file_name;
00024 FILE *outfp;
00025 int true_color;
00026 int width, height;
00027 int encapsulated;
00028 int no_header, no_trailer;
00029 
00030 static int landscape;
00031 static int left, right, bot, top;
00032 
00033 struct paper
00034 {
00035     const char *name;
00036     double width, height;
00037     double left, right, bot, top;
00038 };
00039 
00040 static const struct paper papers[] = {
00041     /* name         width   height  left    right   bottom  top */
00042     {"a4", 8.268, 11.693, 0.5, 0.5, 1.0, 1.0},
00043     {"a3", 11.693, 16.535, 0.5, 0.5, 1.0, 1.0},
00044     {"a2", 16.54, 23.39, 1.0, 1.0, 1.0, 1.0},
00045     {"a1", 23.39, 33.07, 1.0, 1.0, 1.0, 1.0},
00046     {"a0", 33.07, 46.77, 1.0, 1.0, 1.0, 1.0},
00047     {"us-legal", 8.5, 14.0, 1.0, 1.0, 1.0, 1.0},
00048     {"us-letter", 8.5, 11.0, 1.0, 1.0, 1.0, 1.0},
00049     {"us-tabloid", 11.0, 17.0, 1.0, 1.0, 1.0, 1.0},
00050     {NULL, 0, 0, 0, 0, 0, 0}
00051 };
00052 
00053 static void write_prolog(void)
00054 {
00055     char prolog_file[GPATH_MAX];
00056     char date_str[256];
00057     FILE *prolog_fp;
00058     time_t t = time(NULL);
00059     struct tm *tm = localtime(&t);
00060 
00061     strftime(date_str, sizeof(date_str), DATE_FORMAT, tm);
00062 
00063     sprintf(prolog_file, "%s/etc/psdriver.ps", G_gisbase());
00064 
00065     prolog_fp = fopen(prolog_file, "r");
00066     if (!prolog_fp)
00067         G_fatal_error("Unable to open prolog file");
00068 
00069     if (encapsulated)
00070         output("%%!PS-Adobe-3.0 EPSF-3.0\n");
00071     else
00072         output("%%!PS-Adobe-3.0\n");
00073 
00074     output("%%%%LanguageLevel: %d\n", 3);
00075     output("%%%%Creator: GRASS PS Driver\n");
00076     output("%%%%Title: %s\n", file_name);
00077     output("%%%%For: %s\n", G_whoami());
00078     output("%%%%Orientation: %s\n", landscape ? "Landscape" : "Portrait");
00079     output("%%%%BoundingBox: %d %d %d %d\n", left, bot, right, top);
00080     output("%%%%CreationDate: %s\n", date_str);
00081     output("%%%%EndComments\n");
00082 
00083     output("%%%%BeginProlog\n");
00084     while (!feof(prolog_fp)) {
00085         char buf[256];
00086 
00087         if (!fgets(buf, sizeof(buf), prolog_fp))
00088             break;
00089 
00090         fputs(buf, outfp);
00091     }
00092     output("%%%%EndProlog\n");
00093 
00094     fclose(prolog_fp);
00095 }
00096 
00097 void write_setup(void)
00098 {
00099     output("%%%%BeginSetup\n");
00100 
00101     output("%d %d translate\n", left, bot);
00102 
00103     if (landscape)
00104         output("90 rotate 0 1 -1 scale\n");
00105     else
00106         output("0 %d translate 1 -1 scale\n", height);
00107 
00108     output("%d %d BEGIN\n", width, height);
00109 
00110     output("%%%%EndSetup\n");
00111     output("%%%%Page: 1 1\n");
00112 }
00113 
00114 static int in2pt(double x)
00115 {
00116     return (int)(x * 72);
00117 }
00118 
00119 static void swap(int *x, int *y)
00120 {
00121     int tmp = *x;
00122 
00123     *x = *y;
00124     *y = tmp;
00125 }
00126 
00127 static void get_paper(void)
00128 {
00129     const char *name = getenv("GRASS_PAPER");
00130     const struct paper *paper;
00131     int i;
00132 
00133     width = screen_right - screen_left;
00134     height = screen_bottom - screen_top;
00135 
00136     left = 0;
00137     right = width;
00138     bot = 0;
00139     top = height;
00140 
00141     if (landscape)
00142         swap(&right, &top);
00143 
00144     if (!name)
00145         return;
00146 
00147     for (i = 0;; i++) {
00148         paper = &papers[i];
00149 
00150         if (!paper->name)
00151             return;
00152 
00153         if (G_strcasecmp(name, paper->name) == 0)
00154             break;
00155     }
00156 
00157     left = in2pt(paper->left);
00158     right = in2pt(paper->width) - in2pt(paper->right);
00159     bot = in2pt(paper->bot);
00160     top = in2pt(paper->height) - in2pt(paper->top);
00161 
00162     width = right - left;
00163     height = in2pt(paper->height) - in2pt(paper->top) - in2pt(paper->bot);
00164 
00165     if (landscape)
00166         swap(&width, &height);
00167 
00168     screen_right = screen_left + width;
00169     screen_bottom = screen_top + height;
00170 }
00171 
00172 int PS_Graph_set(int argc, char **argv)
00173 {
00174     const char *p;
00175 
00176     G_gisinit("PS driver");
00177 
00178     p = getenv("GRASS_PSFILE");
00179     if (!p || strlen(p) == 0)
00180         p = FILE_NAME;
00181 
00182     file_name = p;
00183     p = file_name + strlen(file_name) - 4;
00184     encapsulated = (G_strcasecmp(p, ".eps") == 0);
00185 
00186     p = getenv("GRASS_TRUECOLOR");
00187     true_color = p && strcmp(p, "TRUE") == 0;
00188 
00189     p = getenv("GRASS_LANDSCAPE");
00190     landscape = p && strcmp(p, "TRUE") == 0;
00191 
00192     p = getenv("GRASS_PS_HEADER");
00193     no_header = p && strcmp(p, "FALSE") == 0;
00194 
00195     p = getenv("GRASS_PS_TRAILER");
00196     no_trailer = p && strcmp(p, "FALSE") == 0;
00197 
00198     G_message("PS: GRASS_TRUECOLOR status: %s",
00199               true_color ? "TRUE" : "FALSE");
00200 
00201     get_paper();
00202 
00203     init_color_table();
00204 
00205     outfp = fopen(file_name, no_header ? "a" : "w");
00206 
00207     if (!outfp)
00208         G_fatal_error("Unable to open output file: %s", file_name);
00209 
00210     if (!no_header) {
00211         write_prolog();
00212         write_setup();
00213     }
00214 
00215     G_message
00216         ("PS: collecting to file: %s,\n     GRASS_WIDTH=%d, GRASS_HEIGHT=%d",
00217          file_name, width, height);
00218 
00219     fflush(outfp);
00220 
00221     return 0;
00222 }
00223 
00224 void output(const char *fmt, ...)
00225 {
00226     va_list va;
00227 
00228     va_start(va, fmt);
00229     vfprintf(outfp, fmt, va);
00230     va_end(va);
00231 }
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines