1 /***************************************************************************
2  * define.h is part of Math Graphic Library
3  * Copyright (C) 2007-2016 Alexey Balakin <mathgl.abalakin@gmail.ru>       *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Lesser General Public License  as       *
7  *   published by the Free Software Foundation; either version 3 of the    *
8  *   License, or (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 Lesser General Public     *
16  *   License along with this program; if not, write to the                 *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifndef _MGL_DEFINE_H_
21 #define _MGL_DEFINE_H_
22 //-----------------------------------------------------------------------------
23 // Disable warnings for MSVC:
24 // 4190 - C-linkage of std::complex,
25 // 4996 - deprecated abi functions
26 // 4786 - disable warnings on 255 char debug symbols
27 // 4231 - disable warnings on extern before template instantiation
28 // 4800	- "int,uint32_t,etc" forcing value to bool 'true' or 'false' (performance warning)
29 // 4244 - conversion from 'mreal,double' to 'float', possible loss of data
30 // 4267	- conversion from 'size_t' to 'long,int,etc', possible loss of data
31 // 4305	- truncation from 'double' to 'float'
32 // 4251 - class 'type' needs to have dll-interface to be used by clients of class 'type2'
33 #if defined(_MSC_VER)
34 #pragma warning(disable: 4190 4996 4786 4800 4244 4267 4305 4251)
35 #endif
36 
37 #if defined(_WIN32) && !defined(WIN32)
38 #define WIN32 1
39 #endif
40 
41 #include "mgl2/config.h"
42 #ifndef SWIG
43 
44 #if MGL_HAVE_PTHR_WIDGET|MGL_HAVE_PTHREAD
45 #include <pthread.h>
46 #endif
47 
48 #include "mgl2/dllexport.h"
49 #if defined(MGL_LIB_MSVC)
50 #define MGL_EXTERN
51 #else
52 #define MGL_EXTERN extern
53 #endif
54 
55 #if defined(_MSC_VER)
56 #define MGL_OBSOLETE	MGL_NO_EXPORT
57 #else
58 #define MGL_OBSOLETE	MGL_EXPORT
59 #endif
60 
61 #if MGL_HAVE_ATTRIBUTE
62 #define MGL_FUNC_CONST	__attribute__((const))
63 #define MGL_FUNC_PURE	__attribute__((pure))
64 #define MGL_FUNC_INIT	__attribute__((constructor))
65 #define MGL_FUNC_FINI	__attribute__((destructor))
66 #else
67 #define MGL_FUNC_CONST
68 #define MGL_FUNC_PURE
69 #endif
70 #define MGL_EXPORT_CONST	MGL_EXPORT MGL_FUNC_CONST
71 #define MGL_EXPORT_PURE		MGL_EXPORT MGL_FUNC_PURE
72 #define MGL_LOCAL_CONST		MGL_NO_EXPORT MGL_FUNC_CONST
73 #define MGL_LOCAL_PURE		MGL_NO_EXPORT MGL_FUNC_PURE
74 
75 #if MGL_HAVE_RVAL	// C++11 don't support register keyword
76 #endif
77 
78 #endif
79 //-----------------------------------------------------------------------------
80 #ifdef MGL_SRC
81 
82 #if MGL_USE_GETTEXT
83 	#include <libintl.h>
84 	#define _(x)	gettext(x)
85 #else
86 	#define _(x)	(x)
87 #endif
88 
89 
90 #if MGL_HAVE_ZLIB
91 #include <zlib.h>
92 #ifndef Z_BEST_COMPRESSION
93 #define Z_BEST_COMPRESSION 9
94 #endif
95 #else
96 #define gzFile	FILE*
97 #define gzread(fp,buf,size)	fread(buf,1,size,fp)
98 #define gzopen	fopen
99 #define gzclose	fclose
100 #define gzprintf	fprintf
101 #define gzgets(fp,str,size)	fgets(str,size,fp)
102 #define gzgetc	fgetc
103 #endif
104 #endif
105 
106 #if (defined(_MSC_VER) && (_MSC_VER<1600)) || defined(__BORLANDC__)
107 typedef signed char int8_t;
108 typedef signed short int16_t;
109 typedef signed long int32_t;
110 typedef signed long long int64_t;
111 typedef unsigned char uint8_t;
112 typedef unsigned short uint16_t;
113 typedef unsigned long uint32_t;
114 typedef unsigned long long uint64_t;
115 #else
116 #include <stdint.h>
117 #endif
118 #if defined(__BORLANDC__)
119 typedef unsigned long uintptr_t;
120 #endif
121 
122 #if ((defined(_MSC_VER) || defined(__BORLANDC__)) && !defined(M_PI))	//_MSC_VER needs this before math.h
123 #define	_USE_MATH_DEFINES
124 #endif
125 
126 #include <math.h>
127 #include <stdio.h>
128 #include <stdlib.h>
129 #include <string.h>
130 #include <wchar.h>
131 
132 #if defined(_MSC_VER)
133 typedef long msize;
134 #define collapse(a)	// MSVS don't support OpenMP 3.*
135 #if (_MSC_VER<=1800)
136 #define strtoull _strtoui64
137 //#define hypot	_hypot
138 #define getcwd	_getcwd
139 #define chdir	_chdir // BORLAND has chdir
140 #endif
141 #define snprintf _snprintf
142 #if (_MSC_VER<1600) // based on https://hg.python.org/cpython/rev/9aedb876c2d7
143 #define hypot	_hypot
144 #endif
145 #else
146 typedef size_t msize;
147 #endif
148 
149 #if !MGL_SYS_NAN
150 #include <float.h>
151 const unsigned long long mgl_nan[2] = {0x7fffffffffffffff, 0x7fffffff};
152 const unsigned long long mgl_inf[2] = {0x7ff0000000000000, 0x7f800000};
153 #define NANd    (*(double*)mgl_nan)
154 #define NANf    (*(float*)(mgl_nan+1))
155 #define INFd    (*(double*)mgl_inf)
156 #define INFf    (*(float*)(mgl_inf+1))
157 
158 #if !defined(NAN)
159 #if MGL_USE_DOUBLE
160 #define NAN		NANd
161 #else
162 #define NAN		NANf
163 #endif
164 #endif
165 
166 #if !defined(INFINITY)
167 #if MGL_USE_DOUBLE
168 #define INFINITY	INFd
169 #else
170 #define INFINITY	INFf
171 #endif
172 #endif
173 #endif	// !MGL_SYS_NAN
174 
175 #ifndef M_PI
176 #define M_PI	3.14159265358979323846  /* pi */
177 #endif
178 //-----------------------------------------------------------------------------
179 #ifdef WIN32
180 #define mglprintf    _snwprintf
181 #else
182 #define mglprintf    swprintf
183 #endif
184 //#define FLT_EPS	1.1920928955078125e-07
185 //-----------------------------------------------------------------------------
186 #if MGL_USE_DOUBLE
187 typedef double mreal;
188 #define MGL_EPSILON	(1.+1e-10)
189 #define MGL_MIN_VAL 1e-307
190 #else
191 typedef float mreal;
192 #define MGL_EPSILON	(1.+1e-5)
193 #define MGL_MIN_VAL 1e-37
194 #endif
195 #define MGL_FEPSILON	(1.+1e-5)
196 //-----------------------------------------------------------------------------
197 #ifndef MGL_CMAP_COLOR
198 #define MGL_CMAP_COLOR	32
199 #endif
200 //-----------------------------------------------------------------------------
201 #ifndef MGL_DEF_VIEWER
202 #define MGL_DEF_VIEWER "evince"
203 #endif
204 //-----------------------------------------------------------------------------
205 enum{	// types of predefined curvelinear coordinate systems
206 	mglCartesian = 0,	// no transformation
207 	mglPolar,
208 	mglSpherical,
209 	mglParabolic,
210 	mglParaboloidal,
211 	mglOblate,
212 	mglProlate,
213 	mglElliptic,
214 	mglToroidal,
215 	mglBispherical,
216 	mglBipolar,
217 	mglLogLog,
218 	mglLogX,
219 	mglLogY
220 };
221 //-----------------------------------------------------------------------------
222 // types of drawing
223 #define MGL_DRAW_WIRE	0	// fastest, no faces
224 #define MGL_DRAW_FAST	1	// fast, no color interpolation
225 #define MGL_DRAW_NORM	2	// high quality, slower
226 #define MGL_DRAW_LMEM	4	// low memory usage (direct to pixel)
227 #define MGL_DRAW_DOTS	8	// draw dots instead of primitives
228 #define MGL_DRAW_NONE	9	// no ouput (for testing only)
229 //-----------------------------------------------------------------------------
230 enum{	// Codes for warnings/messages
231 	mglWarnNone = 0,// Everything OK
232 	mglWarnDim,		// Data dimension(s) is incompatible
233 	mglWarnLow,		// Data dimension(s) is too small
234 	mglWarnNeg,	 	// Minimal data value is negative
235 	mglWarnFile, 	// No file or wrong data dimensions
236 	mglWarnMem,		// Not enough memory
237 	mglWarnZero, 	// Data values are zero
238 	mglWarnLeg,		// No legend entries
239 	mglWarnSlc,		// Slice value is out of range
240 	mglWarnCnt,		// Number of contours is zero or negative
241 	mglWarnOpen, 	// Couldn't open file
242 	mglWarnLId,		// Light: ID is out of range
243 	mglWarnSize, 	// Setsize: size(s) is zero or negative
244 	mglWarnFmt,		// Format is not supported for that build
245 	mglWarnTern, 	// Axis ranges are incompatible
246 	mglWarnNull, 	// Pointer is NULL
247 	mglWarnSpc,		// Not enough space for plot
248 	mglScrArg,		// Wrong argument(s) in MGL script
249 	mglScrCmd,		// Wrong command in MGL script
250 	mglScrLong,		// Too long line in MGL script
251 	mglScrStr,		// Unbalanced ' in MGL script
252 	mglScrTemp,		// Change temporary data in MGL script
253 	mglWarnEnd		// Maximal number of warnings (must be last)
254 };
255 //-----------------------------------------------------------------------------
256 #define MGL_DEF_PAL	"bgrcmyhlnqeupH"	// default palette
257 #define MGL_DEF_SCH	"BbcyrR"	// default palette
258 #define MGL_COLORS	"kwrgbcymhWRGBCYMHlenpquLENPQU"
259 //-----------------------------------------------------------------------------
260 /// Brushes for mask with symbol "-+=;oOsS~<>jdD*^" correspondingly
261 extern MGL_EXPORT uint64_t mgl_mask_val[16];
262 #define MGL_MASK_ID		"-+=;oOsS~<>jdD*^"
263 #define MGL_SOLID_MASK	0xffffffffffffffff
264 //-----------------------------------------------------------------------------
265 #define MGL_TRANSP_NORM		0x00000000
266 #define MGL_TRANSP_GLASS 	0x00000001
267 #define MGL_TRANSP_LAMP		0x00000002
268 #define MGL_ENABLE_CUT		0x00000004 	///< Flag which determines how points outside bounding box are drown.
269 #define MGL_ENABLE_RTEXT 	0x00000008 	///< Use text rotation along axis
270 #define MGL_AUTO_FACTOR		0x00000010 	///< Enable autochange PlotFactor
271 #define MGL_ENABLE_ALPHA 	0x00000020 	///< Flag that Alpha is used
272 #define MGL_ENABLE_LIGHT 	0x00000040 	///< Flag of using lightning
273 #define MGL_TICKS_ROTATE 	0x00000080 	///< Allow ticks rotation
274 #define MGL_TICKS_SKIP		0x00000100 	///< Allow ticks rotation
275 // flags for internal use only
276 #define MGL_DISABLE_SCALE	0x00000200 	///< Temporary flag for disable scaling (used for axis)
277 #define MGL_FINISHED 		0x00000400 	///< Flag that final picture (i.e. mglCanvas::G) is ready
278 #define MGL_USE_GMTIME		0x00000800 	///< Use gmtime instead of localtime
279 #define MGL_SHOW_POS		0x00001000 	///< Switch to show or not mouse click position
280 #define MGL_CLF_ON_UPD		0x00002000 	///< Clear plot before Update()
281 #define MGL_NOSUBTICKS		0x00004000 	///< Disable subticks drawing (for bounding box)
282 #define MGL_LOCAL_LIGHT		0x00008000 	///< Keep light sources for each inplot
283 #define MGL_VECT_FRAME		0x00010000 	///< Use DrwDat to remember all data of frames
284 #define MGL_REDUCEACC		0x00020000 	///< Reduce accuracy of points (to reduce size of output files)
285 #define MGL_PREFERVC 		0x00040000 	///< Prefer vertex color instead of texture if output format supports
286 #define MGL_ONESIDED 		0x00080000 	///< Render only front side of surfaces if output format supports (for debugging)
287 #define MGL_NO_ORIGIN 		0x00100000 	///< Don't draw tick labels at axis origin
288 #define MGL_GRAY_MODE 		0x00200000 	///< Convert all colors to gray ones
289 #define MGL_FULL_CURV 		0x00400000 	///< Disable omitting points in straight-line part(s).
290 #define MGL_NO_SCALE_REL 	0x00800000 	///< Disable font scaling in relative inplots
291 //-----------------------------------------------------------------------------
292 #ifdef __cplusplus
293 #include <string>
294 #include <vector>
295 #include <complex>
296 typedef std::complex<mreal> dual;
297 typedef std::complex<double> ddual;
298 //-----------------------------------------------------------------------------
mgl_isrange(double a,double b)299 inline bool mgl_isrange(double a, double b)
300 {	return fabs(a-b)>MGL_MIN_VAL && a-a==0. && b-b==0.;	}
mgl_isbad(double a)301 inline bool mgl_isbad(double a)	{	return a-a!=0;	}
mgl_isbad(dual a)302 inline bool mgl_isbad(dual a)	{	return a-a!=mreal(0);	}
mgl_isfin(double a)303 inline bool mgl_isfin(double a)	{	return a-a==0;	}
mgl_isfin(dual a)304 inline bool mgl_isfin(dual a)	{	return a-a==mreal(0);	}
mgl_isnum(double a)305 inline bool mgl_isnum(double a)	{	return a==a;	}
mgl_isnum(dual a)306 inline bool mgl_isnum(dual a)	{	return a==a;	}
mgl_isnan(double a)307 inline bool mgl_isnan(double a)	{	return a!=a;	}
mgl_isnan(dual a)308 inline bool mgl_isnan(dual a)	{	return a!=a;	}
mgl_sign(double a)309 inline int mgl_sign(double a)	{	return a<0?-1:1;	}
mgl_int(double a)310 inline long mgl_int(double a)	{	return long(a+(a>=0?0.5:-0.5));	}
mgl_min(double a,double b)311 inline double mgl_min(double a, double b)	{	return a>b?b:a;	}
mgl_max(double a,double b)312 inline double mgl_max(double a, double b)	{	return a>b?a:b;	}
mgl_imin(long a,long b)313 inline long mgl_imin(long a, long b)	{	return a>b?b:a;	}
mgl_imax(long a,long b)314 inline long mgl_imax(long a, long b)	{	return a>b?a:b;	}
mgl_strncpy(char * a,const char * b,size_t s)315 inline void mgl_strncpy(char *a, const char *b, size_t s)	{	strncpy(a,b,s);	a[s-1]=0;	}
316 //-----------------------------------------------------------------------------
317 extern "C" {
318 #endif
319 //-----------------------------------------------------------------------------
320 struct cmdual	// complex number (bypass C/C++ incompatibility)
321 {
322 	mreal re,im;	// real and imaginary parts
323 #ifdef __cplusplus
dualcmdual324 	operator dual() const	{	return dual(re,im);	}
realcmdual325 	mreal real() const	{	return re;	}
imagcmdual326 	mreal imag() const	{	return im;	}
327 #endif
328 };
329 #ifdef __cplusplus
330 struct mdual : public cmdual
331 {
mdualmdual332 	mdual(const cmdual &c)	{	re=c.re;	im=c.im;	}
mdualmdual333 	mdual(const std::complex<float> &c)	{	re=c.real();	im=c.imag();	}
mdualmdual334 	mdual(const std::complex<double> &c){	re=c.real();	im=c.imag();	}
335 	mdual(mreal r=0, mreal i=0)	{	re=r;	im=i;	}
336 	mdual &operator=(const cmdual &c)	{	re=c.re;	im=c.im;	return *this;	}
337 	mdual &operator=(const std::complex<float> &c)	{	re=c.real();	im=c.imag();	return *this;	}
338 	mdual &operator=(const std::complex<double> &c)	{	re=c.real();	im=c.imag();	return *this;	}
339 	mdual &operator=(mreal r)	{	re=r;	im=0;	return *this;	}
340 };
341 #else
342 typedef struct cmdual cmdual;
343 typedef cmdual mdual;
344 #if MGL_HAVE_C99_COMPLEX
345 	#include <complex.h>
346 	#if MGL_USE_DOUBLE
347 		typedef double _Complex dual;
348 	#else
349 		typedef float _Complex dual;
350 	#endif
351 	MGL_EXPORT dual mdual2c(cmdual c);
352 	MGL_EXPORT cmdual c2mdual(dual c);
353 #endif
354 #endif
355 //-----------------------------------------------------------------------------
356 extern float MGL_EXPORT mgl_cos[360];	///< contain cosine with step 1 degree
357 void MGL_EXPORT MGL_FUNC_INIT mgl_init();	///< initialize MathGL structures
358 void MGL_EXPORT MGL_FUNC_FINI mgl_fini();	///< free MathGL structures
359 //-----------------------------------------------------------------------------
360 /// Calculate sqrt(x*x+y*y)
361 double MGL_EXPORT_CONST mgl_hypot(double x, double y);
362 /// Find length of wchar_t string (bypass standard wcslen bug)
363 size_t MGL_EXPORT_PURE mgl_wcslen(const wchar_t *str);
364 /// Get RGB values for given color id or fill by -1 if no one found
365 void MGL_EXPORT mgl_chrrgb(char id, float rgb[3]);
366 /// Get number of colors in the string
367 size_t MGL_EXPORT_PURE mgl_get_num_color(const char *s, int smooth);
368 /// Check if string contain color id and return its number
369 long MGL_EXPORT_PURE mgl_have_color(const char *stl);
370 /// Find symbol in string excluding {} and return its position or NULL
371 MGL_EXPORT_PURE const char *mglchr(const char *str, char ch);
372 /// Find any symbol from chr in string excluding {} and return its position or NULL
373 MGL_EXPORT_PURE const char *mglchrs(const char *str, const char *chr);
374 /// Set number of thread for plotting and data handling (for pthread version only)
375 void MGL_EXPORT mgl_set_num_thr(int n);
376 void MGL_EXPORT mgl_set_num_thr_(int *n);
377 void MGL_EXPORT mgl_test_txt(const char *str, ...);
378 void MGL_EXPORT mgl_set_test_mode(int enable);
379 /// Remove spaces at begining and at the end of the string
380 void MGL_EXPORT mgl_strtrim(char *str);
381 void MGL_EXPORT mgl_wcstrim(wchar_t *str);
382 /** Change register to lowercase (only for ANSI symbols) */
383 void MGL_EXPORT mgl_strlwr(char *str);
384 void MGL_EXPORT mgl_wcslwr(wchar_t *str);
385 /// Convert wchar_t* string into char* one
386 void MGL_EXPORT mgl_wcstombs(char *dst, const wchar_t *src, int size);
387 /// Clear internal data for speeding up FFT and Hankel transforms
388 void MGL_EXPORT mgl_clear_fft();
389 /// Set global warning message
390 void MGL_EXPORT mgl_set_global_warn(const char *text);
391 void MGL_EXPORT mgl_set_global_warn_(const char *text,int);
392 /// Get text of global warning message(s)
393 MGL_EXPORT_PURE const char *mgl_get_global_warn();
394 int MGL_EXPORT mgl_get_global_warn_(char *out, int len);
395 /// Clear global warning message
396 void MGL_EXPORT mgl_clear_global_warn();
397 void MGL_EXPORT mgl_clear_global_warn_();
398 /// Setup gettext usage. NOTE: Russian translation MUST be installed.
399 void MGL_EXPORT mgl_textdomain(const char *argv0, const char *locale);
400 void MGL_EXPORT mgl_textdomain_(const char *locale, int);
401 /// size of var array
402 const int MGL_VS = 'z'-'a'+1;
403 #ifdef __cplusplus
404 }
405 #endif
406 //-----------------------------------------------------------------------------
407 #endif
408 //-----------------------------------------------------------------------------
409