1 /*
2     Gri - A language for scientific graphics programming
3     Copyright (C) 2008 Daniel Kelley
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 
20 // gr.h  -- header file for gr and gri (Copyright 1993 Dan Kelley) You must
21 // #include "gr.h" at start of any C program which uses the gr library.
22 
23 #ifndef _grh_
24 #define         _grh_
25 
26 #include <string>
27 #include <assert.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <math.h>
31 // For getpid etc.
32 #if HAVE_UNISTD_H
33 #include <sys/types.h>
34 #include <unistd.h>
35 #endif
36 
37 // Possibly include debugging malloc header file.
38 #ifdef USE_DBMALLOC
39 #ifdef __linux__
40 #include        <malloc.h>
41 #else
42 #include        <dbmalloc.h>
43 #endif
44 #endif
45 
46 // Standard libraries, malloc, etc (this confuses me)
47 #include <stdlib.h>
48 #if STDC_HEADERS
49 #else
50 #if !defined(MSDOS) && !defined(IS_FREEBSD)
51 #include        <malloc.h>
52 #endif
53 #endif				// Doesn't have stdlib
54 
55 // Should not really need these, but on gcc 2.5.8 on my sparc
56 // machine, they are not prototyped.  I only prototyping them
57 // for GNU cc because e.g. alpha compiler chokes on a
58 // disagreement with /usr/include/stdlib.h
59 #if 0                           // removed 1999-mar-07 to port to AIX
60 #if defined(__GNUC__)
61 extern "C" {
62 	int  pclose(FILE *stream);
63 }
64 #endif
65 #endif
66 
67 
68 #include "types.hh"
69 #include "gr_coll.hh"
70 #include "GriColor.hh"
71 #include "GMatrix.hh"
72 
73 // Useful things to know.
74 #define	_grTempStringLEN	32768 // = 2^15  (was 4096 until 2001-feb-17)
75 #define PASTE_CHAR    char(255)
76 
77 // output file type
78 enum output_file_type {
79 	postscript = 0,
80 	svg = 1,
81 	gif = 2
82 };
83 // Geometrical things.
84 #define PI_VALUE 3.14159265358979323846
85 // Postscript things.
86 #define GR_POINTS_IN_PS_PATH 1499 // really 1500, but be safe
87 #define PT_PER_IN 72.27		// points per inch
88 #define PT_PER_CM 28.45		// points per centimetre
89 #define CM_PER_IN 2.54		// BUG: more digits?
90 #define DEG_PER_RAD 57.29577951	// degrees per radian
91 
92 // An io buffer that resorts to file i/o only if a buffer is exhausted. Used
93 // by gr_textget() and gr_textsave().
94 typedef struct {
95 	FILE           *fp;	// file to read if buffer exhausted
96 	char           *buf;	// the buffer
97 	int             buf_capacity; // chars in buffer
98 	int             buf_position; // next char to read in buffer
99 }               FBUFFER;
100 
101 
102 
103 // Axis properties
104 typedef enum {
105 	gr_axis_BOTTOM = 1,
106 	gr_axis_TOP = 0,
107 	gr_axis_LEFT = 1,
108 	gr_axis_RIGHT = 0,
109 	gr_axis_LOG = 0,
110 	gr_axis_LINEAR = 1
111 } gr_axis_properties;
112 
113 typedef struct {
114 	double width_pt;	// width of pen
115 } gr_pen;
116 
117 // Font numbers.  To add new fonts, use 'extract_font_widths' perlscript to
118 // get size info, then incorporate into grstring.c, in a list before the
119 // gr_charwidth_cm() function.
120 // DO NOT change the =0 below, or you'll mess everything up in grstring (esp in
121 // the gr_drawstring() function).
122 typedef enum {
123 	gr_font_Courier = 0,	// Courier
124 	gr_font_CourierOblique,	// Courier-Oblique
125 	gr_font_CourierBold,	// Courier-Bold
126 	gr_font_CourierBoldOblique, // Courier-BoldOblique
127 	gr_font_Helvetica,	// Helvetica
128 	gr_font_HelveticaOblique, // Helvetica-Oblique
129 	gr_font_HelveticaBold,	// Helvetica-Bold
130 	gr_font_HelveticaBoldOblique,	// Helvetica-BoldOblique
131 	gr_font_PalatinoRoman,	// Palatino-Roman
132 	gr_font_PalatinoItalic,	// Palatino-Italic
133 	gr_font_PalatinoBold,	// Palatino-Bold
134 	gr_font_PalatinoBoldItalic, // Palatino-BoldItalic
135 	gr_font_Symbol,		// Symbol
136 	gr_font_Century,    // called NewCenturySchoolbook sometimes (I guess)
137 	gr_font_TimesRoman,	// Times-Roman
138 	gr_font_TimesItalic,	// Times-Italic
139 	gr_font_TimesBold,	// Times-Bold
140 	gr_font_TimesBoldItalic, // Times-BoldItalic
141 	gr_font_end_of_list
142 } gr_fontID;
143 
144 
145 typedef struct {
146 	gr_fontID       id;
147 	char           *name;
148 } gr_font_info;	// used grstring.c:63 for font_list
149 enum gr_font_encoding { font_encoding_standard, font_encoding_isolatin1};
150 typedef struct {
151 	gr_fontID        id;
152 	gr_font_encoding encoding;
153 	double           size_pt;
154 } gr_font;
155 
156 // Symbol numbers
157 enum gr_symbol_type {
158 	gr_unknown_symbol = -1,
159 	gr_plus_symbol,
160 	gr_times_symbol,
161 	gr_box_symbol,
162 	gr_circ_symbol,
163 	gr_diamond_symbol,
164 	gr_triangleup_symbol,
165 	gr_triangleright_symbol,
166 	gr_triangledown_symbol,
167 	gr_triangleleft_symbol,
168 	gr_asterisk_symbol,
169 	gr_star_symbol,
170 	gr_filledbox_symbol,
171 	gr_bullet_symbol,
172 	gr_filleddiamond_symbol,
173 	gr_filledtriangleup_symbol,
174 	gr_filledtriangleright_symbol,
175 	gr_filledtriangledown_symbol,
176 	gr_filledtriangleleft_symbol,
177 	gr_filledhalfmoonup_symbol,
178 	gr_filledhalfmoondown_symbol
179 };
180 
181 // Color.  Is this used??
182 typedef enum {
183 	bw_model, rgb_model, hsb_model
184 }               gr_color_model;
185 
186 typedef struct {
187 	double          red;
188 	double          green;
189 	double          blue;
190 	double          hue;
191 	double          saturation;
192 	double          brightness;
193 	gr_color_model  color_model;
194 }               gr_color;
195 
196 
197 // Function headers.
198 void            abort_gri(void);
199 bool            delete_ps_file(void);
200 void            gr_begin(int specifications);
201 bool            gr_buffgets(char *s, unsigned int most, FBUFFER * fbuf);
202 void            gr_cmtouser(double x_cm, double y_cm, double *x, double *y);
203 void            gr_comment(const char *message);
204 void            gr_contour(const double x[],
205 			   const double y[],
206 			   /*const*/ GriMatrix<double> &z,
207 			   /*const*/ GriMatrix<bool> &legit,
208 			   int nx,
209 			   int ny,
210 			   double z0,
211 			   const char *lab,
212 			   bool rotate_labels,
213 			   bool whiteunder_labels,
214 			   bool center_labels,
215 			   const GriColor& line_color,
216 			   const GriColor& text_color,
217 			   double contour_minlength,
218 			   double contour_space_first,
219 			   double contour_space_later,
220 			   FILE * out_file);
221 gr_fontID       gr_currentfont(void);
222 gr_font_encoding gr_current_font_encoding();
223 double          gr_currentCapHeight_cm(void);	// From font metric info
224 double          gr_currentXHeight_cm(void);	// From font metric info
225 double          gr_currentAscender_cm(void);	// From font metric info
226 double          gr_currentDesscender_cm(void);	// From font metric info
227 double          gr_currentfontsize_pt(void);
228 #define gr_currentfontsize_cm() (gr_currentfontsize_pt() / PT_PER_CM)
229 double          gr_currentmissingvalue(void);
230 char           *gr_currentPSfilename(void);
231 FILE           *gr_currentPSFILEpointer(void);
232 bool            gr_current_ps_landscape(void);
233 double          gr_currentsymbolsize_pt(void);
234 #define gr_currentsymbolsize_cm() (gr_currentsymbolsize_pt() / PT_PER_CM)
235 double          gr_currentticsize_cm(void);
236 void            gr_drawimage_svg(unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double maskg, double mask_b, int imax, int jmax, double llx_cm, double lly_cm, double urx_cm, double ury_cm, bool insert_placer);
237 void            gr_drawimage(unsigned char *im, unsigned char *imTransform, gr_color_model color_model, unsigned char *mask, double mask_r, double maskg, double mask_b, int imax, int jmax, double llx_cm, double lly_cm, double urx_cm, double ury_cm, bool insert_placer);
238 void            gr_draw_arc_cm(bool filled, double xc, double yc, double r, double angle1, double angle2);
239 void            gr_drawarrow_cm(double x, double y, double xend, double yend, double halfwidth);
240 void            gr_drawarrow2_cm(double x, double y, double xend, double yend, double halfwidth);
241 void            gr_drawarrow3_cm(double x, double y, double xend, double yend, double halfwidth);
242 void            gr_drawerrorbars(double x, double xmin, double xmax, double y, double ymin, double ymax, int type);
243 void            gr_drawsymbol(double xcm, double ycm, gr_symbol_type symbol_name);
244 void            gr_drawxaxis(double y, double xl, double xinc, double xr, double xlabeling, gr_axis_properties side);
245 void            gr_drawxyaxes(double xl, double xinc, double xr, double yb, double yinc, double yt); // FIXME need the starts here
246 void            gr_drawyaxis(double x, double yb, double yinc, double yt, double ylabelling, gr_axis_properties side);
247 void            gr_end(const char *filename);
248 void            gr_error(const char *lab);
249 //
250 // Gridding routines.
251 int             gr_grid1(const std::vector<double> &x,
252 			 const std::vector<double> &y,
253 			 const std::vector<double> &f,
254 			 double x0,
255 			 double y0,
256 			 double xRadius,
257 			 double yRadius,
258 			 int method,
259 			 unsigned int neighbors,
260 			 int enlargements,
261 			 double *fOut);
262 
263 
264 void            gr_hsv2rgb(double h, double s, double br, double *r, double *g, double *b);
265 void            gr_lastxy(double *x, double *y);
266 bool            gr_missing(double x);
267 bool            gr_missingx(double x);
268 bool            gr_missingy(double y);
269 void            gr_moveto_cm(double x_cm, double y_cm);
270 bool            gr_multiple(double x, double d, double precision);
271 bool            gr_onxpage_cm(double x_cm);
272 bool            gr_onypage_cm(double y_cm);
273 double          gr_quad_cm();	// width of "M"
274 void            gr_record_handle(double x_cm, double y_cm);
275 void            gr_record_scale(void);
276 bool            gr_reopen_postscript(const char *new_name);
277 void            gr_rgb2cmyk(double R[], double G[], double B[], unsigned int n,	double c[], double m[], double y[], double k[]);
278 void            gr_rgb2hsb(double r, double g, double b, double *h, double *s, double *br);
279 void            gr_rmoveto_cm(double rx_cm, double ry_cm);
280 void            gr_rmoveto_pt(double rx_pt, double ry_pt);
281 void            gr_rotate_xy(double x, double y, double angle, double *xx, double *yy);
282 void            gr_save_postscript(const char *PS_name, int normal_scale);
283 void            gr_scale125(double xl, double xr, int n, double *xlr, double *xrr, int *nr);
284 // Routines to set various things
285 void            gr_set_clip_ps_curve(const double *xc, const double *yc, unsigned int len);
286 void            gr_set_clip_ps_rect(double ll_x_pt, double ll_y_pt, double ur_x_pt, double ur_y_pt);
287 void            gr_set_clip_ps_off();
288 bool            gr_set_dash(std::vector<double> dash);
289 void            gr_setfont(gr_fontID newID, bool force = false);
290 #define gr_setfontsize_cm(f) (gr_setfontsize_pt(f * PT_PER_CM))
291 void            gr_setfontsize_pt(double new_fontsize_pt);
292 void            gr_set_font_encoding(gr_font_encoding encoding);
293 bool            gr_using_missing_value();
294 void            gr_set_missing_value(double missingvalue);
295 void            gr_set_missing_value_none();
296 void            gr_setscale(double xfactor, double yfactor);
297 #define gr_setsymbolsize_cm(s) (gr_setsymbolsize_pt(s * PT_PER_CM))
298 void            gr_setsymbolsize_pt(double size_pt);
299 void            gr_setticdirection(bool tics_point_in);
300 void            gr_setticsize_cm(double newsize_cm);
301 void            gr_settranslate(double xcm, double ycm);
302 void            gr_setup_creatorname(const char *s);
303 void            gr_setup_ps_filename(const char *new_name);
304 void            gr_setup_ps_landscape(void);
305 void            gr_setup_ps_portrait(void);
306 void            gr_setup_ps_scale(double xfactor, double yfactor);
307 void            gr_setxaxisstyle(int xstyle);
308 void            gr_setxlabel(const char *xlab);
309 void            gr_setxnumberformat(const char *xformat);
310 void            gr_setxpagesize_cm(double x_cm);
311 void            gr_setxscale(double xl_cm, double xr_cm, double xl, double xr);
312 void            gr_setxsubdivisions(int num);
313 void            gr_setxtransform(gr_axis_properties xstyle);
314 void            gr_setyaxisstyle(int ystyle);
315 void            gr_setylabel(const char *ylab);
316 void            gr_setynumberformat(const char *yformat);
317 void            gr_setypagesize_cm(double y_cm);
318 void            gr_setyscale(double yb_cm, double yt_cm, double yb, double yt);
319 void            gr_setysubdivisions(int num);
320 void            gr_setytransform(gr_axis_properties ystyle);
321 void            gr_show_at(/*const*/ char *lab, double xcm, double ycm, gr_textStyle style, double angle);
322 void            gr_show_in_box(/*const */GriString &s, const GriColor& text_color, const GriColor& box_color, double x, double y, double angle_deg);
323 void            gr_showpage(void);
324 bool            gr_smootharray(double dx, double dy, double dt, GriMatrix<double> &z, GriMatrix<double> &zS, GriMatrix<bool> &legit, GriMatrix<bool> &legitS, int nx, int ny, int method);
325 void            gr_stringwidth(const char *s, double *x_cm, double *ascent_cm, double *descent_cm);
326 bool            gr_textget(char *s, int max);
327 bool            gr_textsave(const char *s);
328 void            gr_textput(const char *s);
329 double          gr_thinspace_cm();	// 1/6 width of "M"
330 void            gr_usertocm(double x, double y, double *x_cm, double *y_cm);
331 double          gr_usertocm_x(double x, double y);
332 double          gr_usertocm_y(double x, double y);
333 void            gr_usertopt(double x, double y, double *x_pt, double *y_pt);
334 
335 // Equation of state
336 double rho(double S, double T, double p);
337 double pot_temp(double S, double t, double p, double pref);
338 double lapse_rate(double S, double t, double p);
339 
340 
341 // Macros
342 
343 // Pin number to a range
344 #if !defined(pin0_1)
345 #define pin0_1(x)  	((x) < 0 ? 0 : ((x) <   1 ? (x) :   1))
346 #endif
347 #if !defined(pin0_255)
348 #define pin0_255(x)	((x) < 0 ? 0 : ((x) < 255 ? (x) : 255))
349 #endif
350 
351 // Allocate storage, printing file/line if cannot
352 #if !defined(GET_STORAGE)
353 #define GET_STORAGE(var, type, num)					\
354 {									\
355     if ((num) > 0) {							\
356 	if (! ((var) = ( type *) malloc( (num) * sizeof(type)))) {	\
357 	    gr_Error("Out of memory");					\
358 	}								\
359     } else {								\
360 	gr_Error("Cannot allocate zero or fewer bytes of storage");	\
361     }									\
362 }
363 #endif
364 
365 #define interpolate_linear(x,  x0,  y0,  x1,  y1)                       \
366     ((y0) + ((x) - (x0)) * ((y1) - (y0)) / ((x1) - (x0)))
367 
368 
369 // Take care of the fact that the standard c++ library CHANGED the name
370 // of the string::remove to string::erase, as evidenced by the change
371 // in g++ from versions 2.7.x to 2.8.x (early 1998).
372 
373 #if defined(HAVE_OLD_STRING)
374 #define STRINGERASE remove
375 #define STRING_NPOS NPOS
376 #else
377 #define STRINGERASE erase
378 #define STRING_NPOS std::string::npos
379 #endif
380 
381 // Time type (time_t, int, or long) varies per machine (ug).
382 #if defined(VMS) || defined(MSDOS) || defined(IS_DEC_ALPHA) || defined(AIX) || defined(IS_FREEBSD) || defined(IS_NETBSD) || defined(IS_OPENBSD)
383 #define SECOND_TYPE time_t
384 #else
385 #if defined(__DECCXX)
386 #define SECOND_TYPE int
387 #else
388 #define SECOND_TYPE long
389 #endif
390 #endif
391 
392 
393 #endif				// not _gr_
394