GRASS Programmer's Manual
6.4.2(2012)
|
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 }