gdchart0.11.5dev/0000755000175000001440000000000010160627030014275 5ustar ubverdusers00000000000000gdchart0.11.5dev/array_alloc.c0000644000175000001440000001275610160620530016742 0ustar ubverdusers00000000000000/* GDCHART 0.11.2dev ARRAY_ALLOC.C Mar 2002 */ /* Copyright Bruce Verderaime 2002-2004 */ /* Contributed in part or whole by Don Fasen and Darren Kent */ #if !defined (__GNUC__) || defined (__STRICT_ANSI__) #include #include "array_alloc.h" /*F*************************************************************************** * * Function Name: allocate_array_float * * Function Prototype: float ** allocate_array_float (int nr, int nc) * * Allocates memory for a two-dimensional array of floats * referenced as arr[r][c] * *************************************************************************** * * access array as arr[i1=0-nr][i2=0-nc] = *(&arr[0][0]+nr*i1+i2) * row col makes fewest pointer array elements * assuming Ncol>>Nrow * Ex: NC=2 * _______ __________ * **arr |arr[0] |------>arr[0]-->|arr[0][0] | * |_______| |__________| * |arr[1] |----- |arr[0][1] | * |_______| | |__________| * | . | --------->|arr[1][0] | * | . | |__________| * |_______| |arr[1][1] | * |arr[NR-1] * | | * pointer array data array * ****************************************************************************** * * Parameters : * * Name Type Use Description * ---- ---- --- ----------- * nr int Input Number of rows * nc int Input Number of columns * ****************************************************************************** * * Function Return: float** with allocated memory all set up as float[][]. * ****************************************************************************** * * Author: Don Fasen * Date : 12/18/98 * Modified: Darren Kent 20/03/2002 * ****************************************************************************F*/ float ** allocate_array_float( int nr, /* number of pointer array elements */ int nc ) /* larger number for min memory usage */ { int i; float **arr; /* Try to allocate memory for the pointer array, 'nr' pointers-to-float: */ arr = (float**)malloc( nr * sizeof(float*) ); /* no test for success ala glib, i.e., if you're outa memory, ... */ #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc pointer array in allocate_array_float()\n" ); exit( 2 ); } #endif /* Now allocate memory for the data array, 'nr * nc' floats: */ arr[0] = (float*)malloc( nr * nc * sizeof(float) ); #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc data array in allocate_array_float()\n" ); exit( 2 ); } #endif /* fill in the array pointers to point to successive columns. */ /* Don't need to do the first (zeroth) one, because it was set up by the data malloc. */ /* Note that adding 1 to (float*)a.arr[0] adds sizeof(float*) automatically. */ for (i = 1; i < nr; i++) arr[i] = arr[0] + i*nc; return arr; } /* End of FUNCTION allocate_array_float */ /*********************************************************************************** * * Same Implementation for a Char array. * ************************************************************************************/ char ** allocate_array_char( int nr, int nc ) { int i; char **arr; /* Try to allocate memory for the pointer array, 'nr' pointers-to-chars: */ arr = (char**)malloc( nr * sizeof(char*) ); /* no test for success ala glib, i.e., if you're outa memory, ... */ #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc pointer array in allocate_array_char()\n" ); exit( 2 ); } #endif /* Now allocate memory for the data array, 'nr * nc' char: */ arr[0] = (char*)malloc( nr * nc * sizeof(char) ); #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc data array in allocate_array_char()\n" ); exit( 2 ); } #endif /* fill in the array pointers to point to successive columns. */ /* Don't need to do the first (zeroth) one, because it was set up by the data malloc. */ /* Note that adding 1 to (char*)a.arr[0] adds sizeof(char*) automatically. */ for (i = 1; i < nr; i++) arr[i] = arr[0] + i*nc; return arr; } /* End of FUNCTION allocate_array_char */ /*********************************************************************************** * * Same Implementation for a Int array. * ************************************************************************************/ int ** allocate_array_int( int nr, int nc ) { int i; int **arr; /* Try to allocate memory for the pointer array, 'nr' pointers-to-ints: */ arr = (int**)malloc( nr * sizeof(int*) ); /* no test for success ala glib, i.e., if you're outa memory, ... */ #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc pointer array in allocate_array_int()\n" ); exit( 2 ); } #endif /* Now allocate memory for the data array, 'nr * nc' int: */ arr[0] = (int*)malloc( nr * nc * sizeof(int) ); #ifdef DBUG if( arr == NULL ) { perror( "Unable to malloc data array in allocate_array_int()\n" ); exit( 2 ); } #endif /* fill in the array pointers to point to successive columns. */ /* Don't need to do the first (zeroth) one, because it was set up by the data malloc. */ /* Note that adding 1 to (int*)a.arr[0] adds sizeof(int*) automatically. */ for (i = 1; i < nr; i++) arr[i] = arr[0] + i*nc; return arr; } /* End of FUNCTION allocate_array_int */ #endif /* !defined (__GNUC__) || defined (__STRICT_ANSI__) */ gdchart0.11.5dev/array_alloc.h0000644000175000001440000000247410160620521016743 0ustar ubverdusers00000000000000/* GDCHART 0.11.2dev ARRAY_ALLOC.H Mar 2002 */ /* Copyright Bruce Verderaime 2002-2004 */ /* Contributed in part or whole by Don Fasen and Darren Kent */ #ifndef _ARRAY_ALLOC_H #define _ARRAY_ALLOC_H /* ----- no dynamic auto array, need to mallocate space ----- */ #if !defined (__GNUC__) || defined (__STRICT_ANSI__) #include float **allocate_array_float( int nrs, int ncs ); char **allocate_array_char( int nrs, int ncs ); int **allocate_array_int( int nrs, int ncs ); #define CREATE_ARRAY1( arr, type, nels ) type *arr = (type*)malloc( (nels) * sizeof(type) ) /* array2 can't do ptr (*) types */ #define CREATE_ARRAY2( arr, type, nrs, ncs ) type **arr = allocate_array_##type( nrs, ncs ) #define FREE_ARRAY1( arr ) if( arr ) { free( (void*)arr ); arr = NULL; } else #define FREE_ARRAY2( arr ) if( arr ) \ { \ if( arr[0] ) \ free( (void*)arr[0] ); \ free( (void*)arr ); \ arr = NULL; \ } \ else /* ----- avoid alloc, let the stack do the work ----- */ #else #define CREATE_ARRAY1( arr, type, nels ) type arr[ nels ] #define CREATE_ARRAY2( arr, type, nrs, ncs ) type arr[ nrs ][ ncs ] #define FREE_ARRAY1( arr ) #define FREE_ARRAY2( arr ) #endif #endif /*_ARRAY_ALLOC_H */ gdchart0.11.5dev/ft_samp.c0000644000175000001440000000570610160626253016110 0ustar ubverdusers00000000000000/* GDCHART 0.11.1b 3D Bar sample 17 June 2001 */ /* NOTE: fonts and locations specified are machine specific */ /* should be able to set font-search-path env GDFONTPATH */ /* see libgd documentation */ /* will default to builtin font, if specified TTF not found */ #include #include "gdc.h" #include "gdchart.h" #define NUM_SETS 1 #define NUM_POINTS 4 main() { float data [ NUM_SETS ][ NUM_POINTS ]; unsigned long extclr[ NUM_SETS ][ NUM_POINTS ]; char *lbls[] = { "angle - 45", "font - zirkle", "ptsz - 10", "Color - blue", "" }; get_data( data, 0, 500 ); get_individual_colors( extclr ); GDC_BGColor = 0xFFFFFF; GDC_PlotColor = 0x4080FF; GDC_ExtColor = &(extclr[0][0]); /* set color option */ GDC_title = "GDC_title\r\n(benjamingothic 12)"; GDC_title_font = "/usr/share/enlightenment/E-docs/benjamingothic.ttf"; GDC_title_ptsize = 12; GDC_xtitle = "GDC_xtitle\r\n(x-files 12)"; GDC_xtitle_font = "/usr/share/enlightenment/E-docs/x-files.ttf"; GDC_xtitle_ptsize = 12; GDC_ytitle = "GDC_ytitle\r\n(times 10 i)"; GDC_ytitle_font = "/dos/C/windows/fonts/timesi.ttf"; GDC_ytitle_ptsize = 10; GDC_xaxis_angle = 45.0; GDC_xaxis_font = "/usr/share/enlightenment/themes/DEFAULT/ttfonts/zirkle.ttf"; GDC_xaxis_ptsize = 11.0; GDC_XLabelColor = 0x000080; GDC_bar_width = 60; /* (%) */ GDC_image_type = GDC_PNG; /* ---- call the lib V0.95b ----- */ GDC_out_graph( 400, 300, /* width, height */ stdout, /* open FILE pointer */ GDC_3DBAR, /* chart type */ NUM_POINTS, /* num points per data set */ lbls, /* X labels array of char* */ 1, /* number of data sets */ (float*)data, /* data */ (float*)NULL ); /* no right-hand-axis data */ exit(0); } /* --------------------------------------------------------- */ /* sample data gathering routine */ /* data can come from anywhere, generally a DB or data file */ /* here it's randomly generated */ /* --------------------------------------------------------- */ #include /* for rand() */ #include /* for seed */ get_data( float data[NUM_SETS][NUM_POINTS], int low, int high ) { int i, j; srand( (unsigned int)time((time_t)NULL) ); for( i=0; i #include "gdc.h" struct GDC_FONT_T GDC_fontc[GDC_numfonts] = { (gdFontPtr)NULL, 8, 5, (gdFontPtr)NULL, 8, 5, (gdFontPtr)NULL, 12, 6, (gdFontPtr)NULL, 13, 7, (gdFontPtr)NULL, 16, 8, (gdFontPtr)NULL, 15, 9 }; /* ------------------------------------------------------------------- *\ * convert from enum GDC_font_size to gd fonts * for now load them all * #defines and #ifdefs might enable loading only needed fonts * gd2.0 is to be built as a shared obj. \* ------------------------------------------------------------------- */ void load_font_conversions() { GDC_fontc[GDC_pad].f = gdFontTiny; GDC_fontc[GDC_TINY].f = gdFontTiny; GDC_fontc[GDC_SMALL].f = gdFontSmall; GDC_fontc[GDC_MEDBOLD].f = gdFontMediumBold; GDC_fontc[GDC_LARGE].f = gdFontLarge; GDC_fontc[GDC_GIANT].f = gdFontGiant; } /* ------------------------------------------------------------------ *\ * count (natural) substrings (new line sep) \* ------------------------------------------------------------------ */ short cnt_nl( char *nstr, int *len ) /* strlen - max seg */ { short c = 1; short max_seg_len = 0; short tmplen = 0; if( !nstr ) { if( len ) *len = 0; return 0; } while( *nstr ) { if( *nstr == '\n' ) { ++c; max_seg_len = MAX( tmplen, max_seg_len ); tmplen = 0; } else ++tmplen; ++nstr; } if( len ) *len = MAX( tmplen, max_seg_len ); /* don't forget last seg */ return c; } /* ------------------------------------------------------------------ *\ * gd out a string with '\n's * handle FTs (TTFs) and gd fonts * gdImageString() draws from the upper left; * gdImageStringFT() draws from lower left (one font height, even with '\n's)! >:-| \* ------------------------------------------------------------------ */ int GDCImageStringNL( gdImagePtr im, struct GDC_FONT_T *f, char *ftfont, double ftptsz, double rad, int x, int y, char *str, int clr, GDC_justify_t justify, char **sts ) { int retval = 0; char *err = NULL; #ifdef HAVE_LIBFREETYPE /* TODO: honor justifies */ if( ftfont && ftptsz ) { /* need one line height */ /* remember last one (will likely be the same) */ /* is this needed? */ /* gdImageStringFT() utilizes some caching */ /* saves a couple floating point trig calls */ static int f1hgt = 0; static double xs, ys; static double lftptsz = 0.0; static char *lftfont = (char*)-1; if( !f1hgt || ( lftfont != ftfont || lftptsz != ftptsz ) ) { f1hgt = GDCfnt_sz( "Aj", 0, ftfont, ftptsz, rad, NULL ).h; xs = (double)f1hgt * sin(rad); ys = (double)(f1hgt-1) * cos(rad); } x += (int)xs; y += (int)ys; if( (err = gdImageStringFT( im, (int*)NULL, clr, ftfont, ftptsz, rad, x, y, str)) == NULL ) { if( sts ) *sts = err; return 0; } else { /* TTF failed */ retval = 1; /* fall through - default to gdFonts */ /* reinstate upper left reference */ x -= (int)xs; y -= (int)ys; } } #endif { int i; int len; int max_len; short strs_num = cnt_nl( str, &max_len ); CREATE_ARRAY1( sub_str, unsigned char, max_len+1 ); /* char sub_str[max_len+1]; */ len = -1; strs_num = -1; i = -1; do { ++i; ++len; sub_str[len] = *(str+i); if( *(str+i) == '\n' || *(str+i) == '\0' ) { int xpos; sub_str[len] = '\0'; ++strs_num; switch( justify ) { case GDC_JUSTIFY_LEFT: xpos = 0; break; case GDC_JUSTIFY_RIGHT: xpos = f->w*(max_len-len); break; case GDC_JUSTIFY_CENTER: default: xpos = f->w*(max_len-len)/2; } if( rad == 0.0 ) gdImageString( im, f->f, x + xpos, y + (f->h-1)*strs_num, sub_str, clr ); else /* if( rad == M_PI/2.0 ) */ gdImageStringUp( im, f->f, x + (f->h-1)*strs_num, y - xpos, sub_str, clr ); len = -1; } } while( *(str+i) ); } if( sts ) *sts = err; return retval; } /* ------------------------------------------------------------------------ *\ * TODO: * * really get a unique color from the color map * \* ------------------------------------------------------------------------ */ long get_uniq_color( gdImagePtr im ) { return 0x123454; } /* ------------------------------------------------------------------------ */ struct fnt_sz_t GDCfnt_sz( char *s, enum GDC_font_size gdfontsz, char *ftfont, double ftfptsz, double rad, /* w,h still relative to horiz. */ char **sts ) { struct fnt_sz_t rtnval; int len; char *err = NULL; #ifdef HAVE_LIBFREETYPE if( ftfont && ftfptsz ) { int brect[8]; /* obtain brect so that we can size the image */ if( (err = gdImageStringFT( (gdImagePtr)NULL, &brect[0], 0, ftfont, ftfptsz, 0.0, /* rad, */ /* always match angled size??? */ 0, 0, s)) == NULL ) { rtnval.h = brect[1] - brect[7]; rtnval.w = brect[2] - brect[0]; if( sts ) *sts = err; return rtnval; } } #endif rtnval.h = cnt_nl(s,&len) * GDC_fontc[gdfontsz].h; rtnval.w = len * GDC_fontc[gdfontsz].w; if( sts ) *sts = err; return rtnval; } /* ------------------------------------------------------------------------ */ void GDC_destroy_image(void *im) { if( im ) gdImageDestroy( (gdImagePtr)im ); } /* ------------------------------------------------------------------------ */ void out_err( int IMGWIDTH, int IMGHEIGHT, FILE *fptr, unsigned long BGColor, unsigned long LineColor, char *err_str ) { gdImagePtr im; int lineclr; int bgclr; if( (GDC_hold_img & GDC_REUSE_IMAGE) && GDC_image != (void*)NULL ) im = GDC_image; else im = gdImageCreate( IMGWIDTH, IMGHEIGHT ); bgclr = gdImageColorAllocate( im, l2gdcal(BGColor) ); lineclr = gdImageColorAllocate( im, l2gdcal(LineColor) ); gdImageString( im, gdFontMediumBold, IMGWIDTH/2 - GDC_fontc[GDC_MEDBOLD].w*strlen(err_str)/2, IMGHEIGHT/3, (unsigned char*)err_str, lineclr ); /* usually GDC_generate_img is used in conjunction with hard or hold options */ if( GDC_generate_img ) { fflush(fptr); /* clear anything buffered */ switch( GDC_image_type ) { #ifdef HAVE_JPEG case GDC_JPEG: gdImageJpeg( im, fptr, GDC_jpeg_quality ); break; #endif case GDC_WBMP: gdImageWBMP( im, lineclr, fptr ); break; case GDC_GIF: gdImageGif( im, fptr); break; case GDC_PNG: default: gdImagePng( im, fptr ); } } if( GDC_hold_img & GDC_EXPOSE_IMAGE ) GDC_image = (void*)im; else gdImageDestroy(im); return; } gdchart0.11.5dev/gdc.h0000644000175000001440000001062310160620566015214 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev GDC.H 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ /* General header common to chart (xy[z]) and pie */ #ifndef _GDC_H #define _GDC_H #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES #endif #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE #endif #include /* uncle */ #ifndef M_PI #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #endif #include #include #ifdef GDC_INCL #include "gd.h" #include "gdfonts.h" #include "gdfontt.h" #include "gdfontmb.h" #include "gdfontg.h" #include "gdfontl.h" #include "array_alloc.h" #endif /* --- backward compatibility --- */ /* may be removed at a later date */ #define GDC_generate_gif GDC_generate_img #define pie_gif GDC_out_pie /* ------------------------------ */ #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #define GDC_NOVALUE -FLT_MAX #define GDC_NULL GDC_NOVALUE #define ABS( x ) ( (x)<0.0? -(x): (x) ) #define MAX( x, y ) ( (x)>(y)?(x):(y) ) #define MIN( x, y ) ( (x)<(y)?(x):(y) ) #define TO_RAD(o) ( (o)/360.0*(2.0*M_PI) ) #define GDC_NOCOLOR 0x1000000L #define GDC_DFLTCOLOR 0x2000000L #define PVRED 0x00FF0000 #define PVGRN 0x0000FF00 #define PVBLU 0x000000FF #define l2gdcal( c ) ((c)&PVRED)>>16 , ((c)&PVGRN)>>8 , ((c)&0x000000FF) #define l2gdshd( c ) (((c)&PVRED)>>16)/2 , (((c)&PVGRN)>>8)/2 , (((c)&0x000000FF))/2 static int _gdccfoo1; static unsigned long _gdccfoo2; #define _gdcntrst(bg) ( ((bg)&0x800000?0x000000:0xFF0000)| \ ((bg)&0x008000?0x000000:0x00FF00)| \ ((bg)&0x000080?0x000000:0x0000FF) ) #define _clrallocate( im, rawclr, bgc ) \ ( (_gdccfoo2=rawclr==GDC_DFLTCOLOR? _gdcntrst(bgc): rawclr), \ (_gdccfoo1=gdImageColorExact(im,l2gdcal(_gdccfoo2))) != -1? \ _gdccfoo1: \ gdImageColorsTotal(im) == gdMaxColors? \ gdImageColorClosest(im,l2gdcal(_gdccfoo2)): \ gdImageColorAllocate(im,l2gdcal(_gdccfoo2)) ) #define _clrshdallocate( im, rawclr, bgc ) \ ( (_gdccfoo2=rawclr==GDC_DFLTCOLOR? _gdcntrst(bgc): rawclr), \ (_gdccfoo1=gdImageColorExact(im,l2gdshd(_gdccfoo2))) != -1? \ _gdccfoo1: \ gdImageColorsTotal(im) == gdMaxColors? \ gdImageColorClosest(im,l2gdshd(_gdccfoo2)): \ gdImageColorAllocate(im,l2gdshd(_gdccfoo2)) ) typedef enum { GDC_GIF = 0, #ifdef HAVE_JPEG GDC_JPEG = 1, #endif GDC_PNG = 2, GDC_WBMP = 3 /* as of gd1.8.3 WBMP is black and white only. */ } GDC_image_type_t; /* ordered by size */ enum GDC_font_size { GDC_pad = 0, GDC_TINY = 1, GDC_SMALL = 2, GDC_MEDBOLD = 3, GDC_LARGE = 4, GDC_GIANT = 5, GDC_numfonts= 6 }; /* GDC[PIE]_fontc depends on this */ typedef enum { GDC_DESTROY_IMAGE = 0, /* default */ GDC_EXPOSE_IMAGE = 1, /* user must call GDC_destroy_image() */ GDC_REUSE_IMAGE = 2 /* i.e., paint on top of */ } GDC_HOLD_IMAGE_T; /* EXPOSE & REUSE */ #ifdef GDC_INCL struct GDC_FONT_T { gdFontPtr f; char h; char w; }; typedef enum { GDC_JUSTIFY_RIGHT, GDC_JUSTIFY_CENTER, GDC_JUSTIFY_LEFT } GDC_justify_t; struct fnt_sz_t { int w; int h; } GDCfnt_sz( char* str, enum GDC_font_size gdfontsz, char* ttfont, double ttfptsz, double angle, char **status ); int GDCImageStringNL( gdImagePtr, struct GDC_FONT_T*, char*, double, double, int, int, char*, int, GDC_justify_t, char** ); void load_font_conversions(); short cnt_nl( char*, int* ); #endif #ifdef GDC_LIB #define EXTERND extern #define DEFAULTO(val) extern struct GDC_FONT_T GDC_fontc[]; #else #define EXTERND #define DEFAULTO(val) = val #endif /**** COMMON OPTIONS ********************************/ #ifndef _GDC_COMMON_OPTIONS #define _GDC_COMMON_OPTIONS EXTERND GDC_image_type_t GDC_image_type DEFAULTO( GDC_PNG ); EXTERND int GDC_jpeg_quality DEFAULTO( -1 ); /* 0-95 */ EXTERND char GDC_generate_img DEFAULTO( TRUE ); EXTERND GDC_HOLD_IMAGE_T GDC_hold_img DEFAULTO( GDC_DESTROY_IMAGE ); EXTERND void *GDC_image DEFAULTO( (void*)NULL ); /* in/out */ #endif /****************************************************/ void GDC_destroy_image( void* ); void out_err( int IMGWIDTH, int IMGHEIGHT, FILE*, unsigned long BGColor, unsigned long LineColor, char *str ); #endif /*!_GDC_H*/ gdchart0.11.5dev/gdc_pie.c0000644000175000001440000006034510160620575016052 0ustar ubverdusers00000000000000/* GDCHART 0.11.3dev GDC_PIE.C 11 Mar 2003 */ /* Copyright Bruce Verderaime 1998-2004 */ /* ELLIPSE (angled/perspective view) */ /* TODO */ /* view on/off/%/deg option should be tied to 3d_angle? */ /* limited in two directions only - by X axis, or Y axis */ /* ELIPSEY [scaling] only one that make sense? */ /* connections between face&background (effects Y axis only?) */ /* sizing still doesn't work - DONE */ /* label distances need to be variable about the ellipse/3d_angle */ /* #define ELLIPSEX 1.00 */ /* #define ELLIPSEY 0.30 */ #define GDC_INCL #define GDC_LIB #include "gdc.h" /* gdc.h before system includes to pick up features */ #include #include "gdcpie.h" /* rem circle: x = rcos(@), y = rsin(@) */ extern struct GDC_FONT_T GDC_fontc[]; #define SET_RECT( gdp, x1, x2, y1, y2 ) gdp[0].x = gdp[3].x = x1, \ gdp[0].y = gdp[1].y = y1, \ gdp[1].x = gdp[2].x = x2, \ gdp[2].y = gdp[3].y = y2 #define PX( x ) ( cx + (int)( ((float)rad*ellipsex)*sin(pscl*(double)(x)) ) ) /* expects a val */ #define PY( x ) ( cy - (int)( ((float)rad*ellipsey)*cos(pscl*(double)(x)) ) ) /* expects a val */ #define CX( i,d ) ( cx + \ (d? xdepth_3D: 0) + \ (int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * sin((double)(slice_angle[0][i])) ) ) #define CY( i,d ) ( cy - \ (d? ydepth_3D: 0) - \ (int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * cos((double)(slice_angle[0][i])) ) ) /* expect slice number: i (index into slice_angle array) *\ * and position on slice: f (0: slice middle, * * 1: leading (clockwise), * * 2: trailing edge) * * and 3D depth: d (0: do depth, * * 1: no depth adjustment) * \* adjusts for explosion */ #define IX( i,f,d ) ( CX(i,d) + (int)( (double)rad*ellipsex * sin((double)(slice_angle[f][i])) ) ) #define IY( i,f,d ) ( CY(i,d) - (int)( (double)rad*ellipsey * cos((double)(slice_angle[f][i])) ) ) /* same as above except o is angle */ #define OX( i,o,d ) ( CX(i,d) + (int)( (double)rad*ellipsex * sin((double)(o)) ) ) #define OY( i,o,d ) ( CY(i,d) - (int)( (double)rad*ellipsey * cos((double)(o)) ) ) #define TO_INT_DEG(o) (int)rint( (double)((o)/(2.0*M_PI)*360.0) ) #define TO_INT_DEG_FLOOR(o) (int)floor( (double)((o)/(2.0*M_PI)*360.0) ) #define TO_INT_DEG_CEIL(o) (int)ceil( (double)((o)/(2.0*M_PI)*360.0) ) #define TO_RAD(o) ( (o)/360.0*(2.0*M_PI) ) /* assume !> 4*PI */ #define MOD_2PI(o) ( (o)>=(2.0*M_PI)? ((o)-(2.0*M_PI)): (((o)<0)? ((o)+(2.0*M_PI)): (o)) ) #define MOD_360(o) ( (o)>=360? (o)-360: (o) ) /* assume !> 720 */ struct tmp_slice_t { int i; /* original index */ char hidden; /* 'behind' top [3D] pie */ float angle; /* radian */ float slice; }; /* radian */ static float pie_3D_rad; /* user requested 3D angle in radians */ /* degrees (radians) between angle a, and depth angle */ /* 1&2, so comparisons can be done. */ #define RAD_DIST1( a ) ( (dist_foo1=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo1>M_PI)? ABS(dist_foo1-2.0*M_PI): dist_foo1) ) #define RAD_DIST2( a ) ( (dist_foo2=ABS(((a>-.00001&&a<.00001)?0.00001:a)-pie_3D_rad)), ((dist_foo2>M_PI)? ABS(dist_foo2-2.0*M_PI): dist_foo2) ) static float dist_foo1, dist_foo2; /* ------------------------------------------------------- *\ * oof! cleaner way??? * order by angle opposite (180) of depth angle * comparing across 0-360 line \* ------------------------------------------------------- */ static int ocmpr( struct tmp_slice_t *a, struct tmp_slice_t *b ) { if( RAD_DIST1(a->angle) < RAD_DIST2(b->angle) ) return 1; if( RAD_DIST1(a->angle) > RAD_DIST2(b->angle) ) return -1; /* a tie (will happen between each slice) */ /* are we within pie_3D_rad */ if( (a->angle < pie_3D_rad) && (pie_3D_rad < a->slice) || (a->slice < pie_3D_rad) && (pie_3D_rad < a->angle) ) return 1; if( (b->slice < pie_3D_rad) && (pie_3D_rad < b->angle) || (b->angle < pie_3D_rad) && (pie_3D_rad < b->slice) ) return -1; /* let slice angle decide */ if( RAD_DIST1(a->slice) < RAD_DIST2(b->slice) ) return 1; if( RAD_DIST1(a->slice) > RAD_DIST2(b->slice) ) return -1; return 0; } /* ======================================================= *\ * PIE * * Notes: * always drawn from 12:00 position clockwise * 'missing' slices don't get labels * sum(val[0], ... val[num_points-1]) is assumed to be 100% \* ======================================================= */ void GDC_out_pie( short IMGWIDTH, short IMGHEIGHT, FILE *img_fptr, /* open file pointer */ GDCPIE_TYPE type, int num_points, char *lbl[], /* data labels */ float val[] ) /* data */ { int i; gdImagePtr im; int BGColor, LineColor, PlotColor, EdgeColor, EdgeColorShd; CREATE_ARRAY1( SliceColor, int, num_points ); /* int SliceColor[num_points] */ CREATE_ARRAY1( SliceColorShd, int, num_points ); /* int SliceColorShd[num_points] */ float rad = 0.0; /* radius */ float ellipsex = 1.0; float ellipsey = 1.0 - (float)GDCPIE_perspective/100.0; float tot_val = 0.0; float pscl; int cx, /* affects PX() */ cy; /* affects PY() */ /* ~ 1% for a size of 100 pixs */ /* label sizes will more dictate this */ float min_grphable = ( GDCPIE_other_threshold < 0? 100.0/(float)MIN(IMGWIDTH,IMGHEIGHT): (float)GDCPIE_other_threshold )/100.0; short num_slices1 = 0, num_slices2 = 0; char any_too_small = FALSE; CREATE_ARRAY1( others, char, num_points ); /* char others[num_points] */ CREATE_ARRAY2( slice_angle, float, 3, num_points ); /* float slice_angle[3][num_points] */ /* must be used with others[] */ char threeD = ( type == GDC_3DPIE ); int xdepth_3D = 0, /* affects PX() */ ydepth_3D = 0; /* affects PY() */ int do3Dx = 0, /* reserved for macro use */ do3Dy = 0; CREATE_ARRAY2( pct_lbl, char, num_points, 16 ); /* sizeof or strlen (GDCPIE_percent_fmt)? */ CREATE_ARRAY1( pct_ftsz, struct fnt_sz_t, num_points ); /* struct fnt_sz_t lbl_ftsz[num_points] */ CREATE_ARRAY1( lbl_ftsz, struct fnt_sz_t, num_points ); /* struct fnt_sz_t lbl_ftsz[num_points] */ #ifdef HAVE_LIBFREETYPE char *gdcpie_title_font = GDCPIE_title_font; char *gdcpie_label_font = GDCPIE_label_font; double gdcpie_title_ptsize = GDCPIE_title_ptsize; double gdcpie_label_ptsize = GDCPIE_label_ptsize; #else char *gdcpie_title_font = NULL; char *gdcpie_label_font = NULL; double gdcpie_title_ptsize = 0.0; double gdcpie_label_ptsize = 0.0; #endif /* GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360); */ pie_3D_rad = TO_RAD( GDCPIE_3d_angle ); xdepth_3D = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0; ydepth_3D = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0; /* xdepth_3D = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0; */ /* ydepth_3D = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0; */ load_font_conversions(); /* ----- get total value ----- */ for( i=0; i 100% */ float this = this_pct*(2.0*M_PI); /* pie-portion */ if( (this_pct > min_grphable) || /* too small */ (!GDCPIE_missing || !GDCPIE_missing[i]) ) /* still want angles */ { int this_explode = GDCPIE_explode? GDCPIE_explode[i]: 0; double this_sin; double this_cos; slice_angle[0][i] = this/2.0+last; /* mid-point on full pie */ slice_angle[1][i] = last; /* 1st on full pie */ slice_angle[2][i] = this+last; /* 2nd on full pie */ this_sin = ellipsex*sin( (double)slice_angle[0][i] ); this_cos = ellipsey*cos( (double)slice_angle[0][i] ); if( !GDCPIE_missing || !(GDCPIE_missing[i]) ) { short lbl_wdth = 0, lbl_hgt = 0; float this_y_explode_limit, this_x_explode_limit; /* start slice label height, width */ /* accounting for PCT placement, font */ pct_ftsz[i].h = 0; pct_ftsz[i].w = 0; if( GDCPIE_percent_fmt && GDCPIE_percent_labels != GDCPIE_PCT_NONE ) { sprintf( pct_lbl[i], GDCPIE_percent_fmt, this_pct * 100.0 ); pct_ftsz[i] = GDCfnt_sz( pct_lbl[i], GDCPIE_label_size, gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL ); lbl_wdth = pct_ftsz[i].w; lbl_hgt = pct_ftsz[i].h; } if( lbl && lbl[i] ) { lbl_ftsz[i] = GDCfnt_sz( lbl[i], GDCPIE_label_size, gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL ); if( GDCPIE_percent_labels == GDCPIE_PCT_ABOVE || GDCPIE_percent_labels == GDCPIE_PCT_BELOW ) { lbl_wdth = MAX( pct_ftsz[i].w, lbl_ftsz[i].w ); lbl_hgt = pct_ftsz[i].h + lbl_ftsz[i].h + 1; } else if( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT || GDCPIE_percent_labels == GDCPIE_PCT_LEFT ) { lbl_wdth = pct_ftsz[i].w + lbl_ftsz[i].w + 1; lbl_hgt = MAX( pct_ftsz[i].h, lbl_ftsz[i].h ); } else /* GDCPIE_PCT_NONE */ { lbl_wdth = lbl_ftsz[i].w; lbl_hgt = lbl_ftsz[i].h; } } else lbl_wdth = lbl_hgt = 0; /* end label height, width */ /* diamiter limited by this point's: explosion, label */ /* (radius to box @ slice_angle) - (explode) - (projected label size) */ /* radius constraint due to labels */ this_y_explode_limit = (float)this_cos==0.0? FLT_MAX: ( (float)( (double)cheight/ABS(this_cos) ) - (float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) - (float)( lbl_hgt/2 ) / (float)ABS(this_cos) ); this_x_explode_limit = (float)this_sin==0.0? FLT_MAX: ( (float)( (double)cwidth/ABS(this_sin) ) - (float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) - (float)( lbl_wdth ) / (float)ABS(this_sin) ); rad = MIN( rad, this_y_explode_limit ); rad = MIN( rad, this_x_explode_limit ); /* ok at this radius (which is most likely larger than final) */ /* adjust for inter-label spacing */ /* if( lbl[i] && *lbl[i] ) */ /* { */ /* char which_edge = slice_angle[0][i] > M_PI? +1: -1; // which semi */ /* last_label_yedge = cheight - (int)( (rad + // top or bottom of label */ /* (float)(this_explode + */ /* (float)GDCPIE_label_dist)) * (float)this_cos ) + */ /* ( (GDC_fontc[GDCPIE_label_size].h+1)/2 + */ /* GDC_label_spacing )*which_edge; */ /* } */ /* radius constriant due to exploded depth */ /* at each edge of the slice, and the middle */ /* this is really stupid */ /* this section uses a different algorithm then above, but does the same thing */ /* could be combined, but each is ugly enough! */ /* PROTECT /0 */ if( threeD ) { short j; int this_y_explode_pos; int this_x_explode_pos; /* first N E S W (actually no need for N) */ if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) && /* E */ (this_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth ) rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin(M_PI_2) ); if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) && /* W */ (this_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth ) rad -= (float)ABS( (double)(this_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) ); if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) && /* S */ (this_y_explode_pos=OY(i,M_PI,1)) > cy+cheight ) rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos(M_PI) ); for( j=0; j<3; ++j ) { this_y_explode_pos = IY(i,j,1); if( this_y_explode_pos < cy-cheight ) rad -= (float)ABS( (double)((cy-cheight)-this_y_explode_pos)/cos((double)slice_angle[j][i]) ); if( this_y_explode_pos > cy+cheight ) rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) ); this_x_explode_pos = IX(i,j,1); if( this_x_explode_pos < cx-cwidth ) rad -= (float)ABS( (double)((cx-cwidth)-this_x_explode_pos)/sin((double)slice_angle[j][i]) ); if( this_x_explode_pos > cx+cwidth ) rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) ); } } } others[i] = FALSE; } else { others[i] = TRUE; slice_angle[0][i] = -FLT_MAX; } last += this; } } /* ----- go ahead and start the image ----- */ im = gdImageCreate( IMGWIDTH, IMGHEIGHT ); /* --- allocate the requested colors --- */ BGColor = clrallocate( im, GDCPIE_BGColor ); LineColor = clrallocate( im, GDCPIE_LineColor ); PlotColor = clrallocate( im, GDCPIE_PlotColor ); if( GDCPIE_EdgeColor != GDC_NOCOLOR ) { EdgeColor = clrallocate( im, GDCPIE_EdgeColor ); if( threeD ) EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor ); } /* --- set color for each slice --- */ for( i=0; i 2 ) { float rad = rad1; /* local override */ gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), edge_color, SliceColorShd[i] ); } } } /* fill in connection to foreground pie */ /* this is where we earn our keep */ { int t, num_slice_angles = 0; CREATE_ARRAY1( tmp_slice, struct tmp_slice_t, 4*num_points+4 ); /* should only need 2*num_points+2 */ for( i=0; iMOD_2PI(pie_3D_rad+M_PI_2) ) { tmp_slice[num_slice_angles].i = i; tmp_slice[num_slice_angles].hidden = FALSE; tmp_slice[num_slice_angles].slice = slice_angle[0][i]; tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 ); } if( slice_angle[1][i]MOD_2PI(pie_3D_rad+3.0*M_PI_2) ) { tmp_slice[num_slice_angles].i = i; tmp_slice[num_slice_angles].hidden = FALSE; tmp_slice[num_slice_angles].slice = slice_angle[0][i]; tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 ); } } qsort( tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr ); for( t=0; t360 */ /* arcs from gdImageFilledArc() don't match with gdImageArc() */ /* angles are off */ /* doesn't always fill completely */ /* gdImageFilledArc( im, CX(i,0), CY(i,0), */ /* (int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0), */ /* (TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360, */ /* (TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360, */ /* SliceColor[i], */ /* gdPie ); */ /* attempt to fill, if slice is wide enough */ { float rad = rad1; /* local override */ if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 ) { gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), edge_color, SliceColor[i] ); } /* catch missed pixels on narrow slices */ gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] ); } } } if( GDCPIE_title ) { struct fnt_sz_t tftsz = GDCfnt_sz( GDCPIE_title, GDCPIE_title_size, gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL ); GDCImageStringNL( im, &GDC_fontc[GDCPIE_title_size], gdcpie_title_font, gdcpie_title_ptsize, 0.0, IMGWIDTH/2 - tftsz.w/2, 1, GDCPIE_title, LineColor, GDC_JUSTIFY_CENTER, NULL ); } /* labels */ if( lbl ) { float liner = rad; rad += GDCPIE_label_dist; for( i=0; i M_PI ) /* which semicircle */ { lblx -= lbl_ftsz[i].w; pctx = lblx; ++linex; } else --linex; switch( GDCPIE_percent_labels ) { case GDCPIE_PCT_LEFT: if( slice_angle[0][i] > M_PI ) pctx -= lbl_ftsz[i].w-1; else lblx += pct_ftsz[i].w+1; pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2; break; case GDCPIE_PCT_RIGHT: if( slice_angle[0][i] > M_PI ) lblx -= pct_ftsz[i].w-1; else pctx += lbl_ftsz[i].w+1; pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2; break; case GDCPIE_PCT_ABOVE: lbly += (1+pct_ftsz[i].h) / 2; pcty = lbly - pct_ftsz[i].h; break; case GDCPIE_PCT_BELOW: lbly -= (1+pct_ftsz[i].h) / 2; pcty = lbly + lbl_ftsz[i].h; break; case GDCPIE_PCT_NONE: default:; } if( GDCPIE_percent_labels != GDCPIE_PCT_NONE ) GDCImageStringNL( im, &GDC_fontc[GDCPIE_label_size], gdcpie_label_font, gdcpie_label_ptsize, 0.0, slice_angle[0][i] <= M_PI? pctx: pctx+lbl_ftsz[i].w-pct_ftsz[i].w, pcty, pct_lbl[i], LineColor, GDC_JUSTIFY_CENTER, NULL ); if( lbl[i] ) GDCImageStringNL( im, &GDC_fontc[GDCPIE_label_size], gdcpie_label_font, gdcpie_label_ptsize, 0.0, lblx, lbly, lbl[i], LineColor, slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT: GDC_JUSTIFY_RIGHT, NULL ); if( GDCPIE_label_line ) { float rad = liner; gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor ); } } } rad -= GDCPIE_label_dist; } fflush( img_fptr ); switch( GDC_image_type ) { #ifdef HAVE_JPEG case GDC_JPEG: gdImageJpeg( im, img_fptr, GDC_jpeg_quality ); break; #endif case GDC_WBMP: gdImageWBMP( im, PlotColor, img_fptr ); break; case GDC_GIF: gdImageGif( im, img_fptr); break; case GDC_PNG: default: gdImagePng( im, img_fptr ); } FREE_ARRAY1( lbl_ftsz ); FREE_ARRAY1( pct_ftsz ); FREE_ARRAY2( pct_lbl ); FREE_ARRAY2( slice_angle ); FREE_ARRAY1( others ); FREE_ARRAY1( SliceColorShd ); FREE_ARRAY1( SliceColor ); gdImageDestroy(im); return; } gdchart0.11.5dev/gdc_pie_samp.c0000644000175000001440000000405310160620604017055 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev PIE SAMPLE 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ /* creates a file "pie.png". Can be stdout for CGI use. */ /* vi: :set tabstop=4 */ #include #include #include "gdc.h" #include "gdcpie.h" main( int argc, char *argv[] ) { /* labels */ char *lbl[] = { "CPQ\n(DEC)", "HP", "SCO", "IBM", "SGI", "SUN\nSPARC", "other" }; /* values to chart */ float p[] = { 12.5, 20.1, 2.0, 22.0, 5.0, 18.0, 13.0 }; FILE *fp = fopen( "pie.png", "wb" ); /* set which slices to explode, and by how much */ int expl[] = { 0, 0, 0, 0, 0, 20, 0 }; /* set missing slices */ unsigned char missing[] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }; /* colors */ unsigned long clr[] = { 0xFF4040L, 0x80FF80L, 0x8080FFL, 0xFF80FFL, 0xFFFF80L, 0x80FFFFL, 0x0080FFL }; /* set options */ /* a lot of options are set here for illustration */ /* none need be - see gdcpie.h for defaults */ /* GDCPIE_title = "Sample\nPIE"; */ GDCPIE_label_line = TRUE; GDCPIE_label_dist = 15; /* dist. labels to slice edge */ /* can be negative */ GDCPIE_LineColor = 0x000000L; GDCPIE_label_size = GDC_SMALL; GDCPIE_3d_depth = 25; GDCPIE_3d_angle = 180; /* 0 - 359 */ GDCPIE_perspective = 70; /* 0 - 99 */ GDCPIE_explode = expl; /* default: NULL - no explosion */ GDCPIE_Color = clr; GDCPIE_BGColor = 0xFFFFFFL; /* GDCPIE_EdgeColor = 0x000000L; default is GDCPIE_NOCOLOR */ /* for no edging */ GDCPIE_missing = missing; /* default: NULL - none missing */ /* add percentage to slice label */ /* below the slice label */ GDCPIE_percent_labels = GDCPIE_PCT_BELOW; GDC_image_type = GDC_PNG; /* call the lib */ GDC_out_pie( 300, /* width */ 200, /* height */ fp, /* open file pointer */ GDC_3DPIE, /* or GDC_2DPIE */ 7, /* number of slices */ NULL, /* can be NULL */ p ); /* data array */ fclose( fp ); exit( 0 ); } gdchart0.11.5dev/gdc_samp1.c0000644000175000001440000000343610160620616016310 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev 1st CHART SAMPLE 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ /* writes gif file to stdout */ /* sample gdchart usage */ /* this will produce a 3D BAR chart */ /* this is suitable for use as a CGI */ /* for CGI use un-comment the "Content-Type" line */ #include #include "gdc.h" #include "gdchart.h" main() { /* ----- set some data ----- */ /* float a[6] = { 0.5, 0.09, 0.6, 0.85, 0.0, 0.90 }, */ /* b[6] = { 1.9, 1.3, 0.6, 0.75, 0.1, 2.0 }; */ float a[2][6] = { { 0.5, 0.09, 0.6, 0.85, 0.0, 0.90 }, { 1.9, 1.3, 0.6, 0.75, 0.1, 2.0 } }; /* ----- X labels ----- */ char *t[6] = { "Chicago", "New York", "L.A.", "Atlanta", "Paris, MD\n(USA) ", "London" }; /* ----- data set colors (RGB) ----- */ unsigned long sc[2] = { 0xFF8080, 0x8080FF }; GDC_BGColor = 0xFFFFFFL; /* backgound color (white) */ GDC_LineColor = 0x000000L; /* line color (black) */ GDC_SetColor = &(sc[0]); /* assign set colors */ /* printf( "Content-Type: image/gif\n\n" ); tell browser type */ GDC_image_type = GDC_GIF; /* ----- call the lib ----- */ GDC_out_graph( 250, 200, /* short width, height */ stdout, /* FILE* open FILE pointer */ GDC_3DBAR, /* GDC_CHART_T chart type */ 6, /* int number of points per data set */ t, /* char*[] array of X labels */ 2, /* int number of data sets */ (float*)a, NULL ); /* float[] data set 1 */ /* b ); ... data set n */ exit(0); } gdchart0.11.5dev/Makefile0000644000175000001440000001071110160616453015744 0ustar ubverdusers00000000000000CC=gcc # gcc 2.7.1 or better is required # CFLAGS= # CFLAGS=-g -ansi -pedantic # ----- build path ----- GDC_INCL=./ GDC_LD=./ GDC_LIB=libgdc.a # ----- install locations ----- PREFIX_INC = /usr/local/include PREFIX_LIB = /usr/local/lib # INCLUDEDIRS=-I. -I/usr/include/freetype2 -I/usr/include/X11 -I/usr/X11R6/include/X11 -I/usr/local/include # ----- lib gd ----- # GDChart requires the gd library - www.boutell.com/gd/ # gd 2.0.28 or better is required (GIF support has returned to libgd) # if it's not installed in a standard location edit these lines for your installation GD_INCL=/usr/local/include/ GD_LD=/usr/local/lib/ GD_LIB=libgd.so # a static libgd is also available # GD_LIB=libgd.a # ----- lib png ----- # libgd requires libpng # if it's not installed in a standard location edit these lines for your installation # PNG_INCL = ../libpng-1.0.8 # PNG_LD = ../libpng-1.0.8 # ----- lib z ----- # libgd requires zlib # if it's not installed in a standard location edit these lines for your installation # ZLIB_INCL = ../zlib-1.1.3 # ZLIB_LD = ../zlib-1.1.3 # ----- lib jpeg ----- # libgd optionally uses libjpeg to produce JPEG images # JPEG_INCL = ../libjpeg # JPEG_LD = ../libjpeg JPEG_DEF = -DHAVE_JPEG JPEG_LK = -ljpeg # libgd optionally uses libfreetype to use TTFs # FT_LD = /usr/local/lib FT_DEF = -DHAVE_LIBFREETYPE FT_LK = -lfreetype DEFS = $(FT_DEF) $(JPEG_DEF) LIBS = $(FT_LK) $(JPEG_LK) LIB_PATHS = -L$(GD_LD) -L$(GDC_LD) # if not installed in standard paths (/lib, /usr/lib), or LD_LIBRARY_PATH # LIB_PATHS = -L$(GD_LD) -L$(PNG_LD) -L$(ZLIB_LD) -L$(JPEG_LD) # NOTE: # libpng, libz, etc. are usually linked in as dynamic libs # either use a link line similar to one of these, or set environment LD_LIBRARY_PATH # these should likely be absolute paths, as resolved at runtime # LIB_PATHS = $(LIB_PATHS) -R$(PNG_LD) -R$(ZLIB_LD) # LIB_PATHS = $(LIB_PATHS) -Xlinker -rpath -Xlinker $(PNG_LD) -Xlinker -rpath -Xlinker $(ZLIB_LD) all: libgdc.a gdc_samp1 gdc_samp2 gdc_pie_samp ft_samp # --- compile the samples --- gdc_pie_samp.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdcpie.h gdc_pie_samp.c $(CC) $(CFLAGS) -I$(GDC_INCL) $(DEFS) -c gdc_pie_samp.c gdc_samp1.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdchart.h gdc_samp1.c $(CC) $(CFLAGS) -I$(GDC_INCL) $(DEFS) -c gdc_samp1.c gdc_samp2.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdchart.h gdc_samp2.c $(CC) $(CFLAGS) -I$(GDC_INCL) $(DEFS) -c gdc_samp2.c ft_samp.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdchart.h ft_samp.c $(CC) $(CFLAGS) -I$(GDC_INCL) $(DEFS) -c ft_samp.c # --- link the samples --- gdc_samp1: $(GDC_LD)libgdc.a gdc_samp1.o $(GD_LD)/$(GD_LIB) $(GDC_LD)/$(GDC_LIB) $(CC) -o gdc_samp1 \ gdc_samp1.o \ $(LIB_PATHS) \ -lgdc -lgd -lz -lpng $(LIBS) -lm gdc_samp2: $(GDC_LD)libgdc.a gdc_samp2.o $(GD_LD)/$(GD_LIB) $(GDC_LD)/$(GDC_LIB) $(CC) -o gdc_samp2 \ gdc.o gdchart.o price_conv.o \ gdc_samp2.o \ $(LIB_PATHS) \ -lgdc -lgd -lz -lpng $(LIBS) -lm gdc_pie_samp: $(GDC_LD)libgdc.a gdc_pie_samp.o $(GD_LD)/$(GD_LIB) $(GDC_LD)/$(GDC_LIB) $(CC) -o gdc_pie_samp \ gdc.o gdc_pie.o price_conv.o \ gdc_pie_samp.o \ $(LIB_PATHS) \ -lgdc -lgd -lz -lpng $(LIBS) -lm ft_samp: $(GDC_LD)libgdc.a ft_samp.o $(GD_LD)/$(GD_LIB) $(GDC_LD)/$(GDC_LIB) $(CC) -o ft_samp \ gdc.o gdchart.o price_conv.o \ ft_samp.o \ $(LIB_PATHS) \ -lgdc -lgd -lz -lpng $(LIBS) -lm # --- compile the lib --- gdc.h: $(GD_INCL)gd.h $(GD_INCL)gdfonts.h $(GD_INCL)gdfontt.h $(GD_INCL)gdfontmb.h $(GD_INCL)gdfontg.h $(GD_INCL)gdfontl.h $(GDC_INCL)array_alloc.h price_conv.o: price_conv.c $(CC) $(CFLAGS) -c price_conv.c gdc.o: gdc.c $(GDC_INCL)gdc.h $(CC) $(CFLAGS) -I$(GD_INCL) -I$(GDC_INCL) $(DEFS) -c gdc.c gdc_pie.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdcpie.h gdc_pie.c $(CC) $(CFLAGS) -I$(GD_INCL) -I$(GDC_INCL) $(DEFS) -c gdc_pie.c gdchart.o: $(GDC_INCL)gdc.h $(GDC_INCL)gdchart.h gdchart.c $(CC) $(CFLAGS) -I$(GD_INCL) -I$(GDC_INCL) $(DEFS) -c gdchart.c array_alloc.o: array_alloc.c array_alloc.h $(CC) $(CFLAGS) -c array_alloc.c libgdc.a: price_conv.o gdc.o gdc_pie.o gdchart.o array_alloc.o ar cr libgdc.a gdc.o gdchart.o gdc_pie.o price_conv.o array_alloc.o ranlib libgdc.a # --- supporting libraries --- # should be compile & installed separately # $(GD_LD)/$(GD_LIB): # cd $(GD_LD) ; make -f Makefile $(GD_LIB) # ----- install ----- install: gdc.h gdchart.h gdcpie.h libgdc.a cp gdc.h gdchart.h gdcpie.h $(PREFIX_INC)/ cp libgdc.a $(PREFIX_LIB)/ # --- clean --- clean: rm -f *.o *.a gdc_samp1 gdc_samp2 gdc_pie_samp ft_samp gdchart0.11.5dev/gdc_samp2.c0000644000175000001440000000515210160620624016305 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev 2nd CHART SAMPLE 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ /* ** vi note :set tabstop=4 ** a more complicated example High Low Close Combo (Volume) with annotation produces a file: g2.png Until a README is ready, see gdchart.h for options All options are defaulted, no need to set any */ #include #include "gdc.h" #include "gdchart.h" main() { /* set some sample data points */ float h[12] = { 17.8, 17.1, 17.3, GDC_NOVALUE, 17.2, 17.1, 17.3, 17.3, 17.3, 17.1, 17.5, 17.4 }; float c[12] = { 17.0, 16.8, 16.9, GDC_NOVALUE, 16.9, 16.8, 17.2, 16.8, 17.0, 16.9, 16.4, 16.1 }; float l[12] = { 16.8, 16.8, 16.7, GDC_NOVALUE, 16.5, 16.0, 16.1, 16.8, 16.5, 16.9, 16.2, 16.0 }; float v[12] = { 150.0, 100.0, 340.0, GDC_NOVALUE, 999.0, 390.0, 420.0, 150.0, 100.0, 340.0, 1590.0, 700.0 }; char *t[12] = { "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Jan", "Feb", "Mar", "Apr" }; /* set color RGB as ulong array */ /* unsigned long setcolor[3] = { 0xC0C0FF, 0xFF4040, 0xFFFFFF }; */ GDC_ANNOTATION_T anno; /* need an open FILE pointer - can be stdout */ FILE *outpng1 = fopen( "g2.png", "wb" ); /* rem: test open() fail */ anno.color = 0x00FF00; strncpy( anno.note, "Did Not\nTrade", MAX_NOTE_LEN ); /* don't exceed MAX_NOTE_LEN */ anno.point = 3; /* first is 0 */ GDC_annotation_font_size = GDC_TINY; GDC_annotation = &anno; /* set annote option */ GDC_HLC_style = GDC_HLC_I_CAP | GDC_HLC_CLOSE_CONNECTED; GDC_HLC_cap_width = 45; GDC_bar_width = 75; /* % */ /* GDC_BGImage = "W.gif"; */ GDC_title = "Widget Corp."; GDC_ytitle = "Price ($)"; GDC_ytitle2 = "Volume (K)"; GDC_ytitle_size = GDC_SMALL; GDC_VolColor = 0x4040FFL; /* aka combo */ GDC_3d_depth = 4.0; /* % entire image */ /* GDC_SetColor = setcolor; /* see README */ GDC_PlotColor = 0xFFFFFF; GDC_grid = FALSE; /* GDC_xtitle="fy.1998"; */ /* fprintf( stdout, "Content-Type: image/png\n\n" ); /* rem: for web use */ /* finally: make the call */ out_graph( 200, 175, /* overall width, height */ outpng1, /* open FILE pointer */ GDC_COMBO_HLC_AREA, /* chart type */ 12, /* number of points */ t, /* X axis label array */ 1, /* number of sets (see README) */ h, /* set 1 (high) */ l, /* low */ c, /* close */ v ); /* combo/volume */ fclose( outpng1 ); exit(0); } gdchart0.11.5dev/gdchart.c0000644000175000001440000021653510160620631016071 0ustar ubverdusers00000000000000/* GDCHART 0.11.3dev GDCHART.C 11 Mar 2003 */ /* Copyright Bruce Verderaime 1998-2004 */ /* vi:set tabstop=4 */ #define GDC_INCL #define GDC_LIB #include "gdc.h" /* gdc.h before system includes to pick up features */ #include #include #include #include #include #include #include "gdchart.h" #define HIGHSET 0 #define LOWSET 1 #define CLOSESET 2 /* scaled translation onto graph */ #define PX( x ) (int)( xorig + (setno*xdepth_3D) + (x)*xscl ) #define PY( y ) (int)( yorig - (setno*ydepth_3D) + (y)*yscl ) #define PV( y ) (int)( vyorig - (setno*ydepth_3D) + (y)*vyscl ) #define SET_RECT( gdp, x1, x2, y1, y2 ) gdp[0].x = gdp[3].x = x1, \ gdp[0].y = gdp[1].y = y1, \ gdp[1].x = gdp[2].x = x2, \ gdp[2].y = gdp[3].y = y2 #define SET_3D_POLY( gdp, x1, x2, y1, y2, xoff, yoff ) \ gdp[0].x = x1, gdp[0].y = y1, \ gdp[1].x = x1+(xoff), gdp[1].y = y1-yoff, \ gdp[2].x = x2+(xoff), gdp[2].y = y2-yoff, \ gdp[3].x = x2, gdp[3].y = y2 /* ------------------------------------------------------------------------- */ /* vals in pixels */ /* ref is front plane */ /* allows for intersecting 3D lines */ /* (also used for single 3D lines >:-Q */ struct YS { int y1; int y2; float slope; int lnclr; int shclr; }; static int qcmpr( const void *a, const void *b ) { if( ((struct YS*)a)->y2 < ((struct YS*)b)->y2 ) return 1; if( ((struct YS*)a)->y2 > ((struct YS*)b)->y2 ) return -1; return 0; } void draw_3d_line( gdImagePtr im, int y0, int x1, int x2, int y1[], int y2[], int xdepth, int ydepth, int num_sets, int clr[], int clrshd[] ) { #define F(x,i) (int)( (float)((x)-x1)*slope[i]+(float)y1[i] ) float depth_slope = xdepth==0? FLT_MAX: (float)ydepth/(float)xdepth; CREATE_ARRAY1( slope, float, num_sets ); /* float slope[num_sets] */ CREATE_ARRAY1( lnclr, int, num_sets ); /* int slope[num_sets] */ CREATE_ARRAY1( shclr, int, num_sets ); /* int slope[num_sets] */ CREATE_ARRAY1( ypts, struct YS, num_sets ); /* struct YS slope[num_sets] */ int i; int x; gdPoint poly[4]; for( i=0; idepth_slope? ypts[i].shclr: ypts[i].lnclr ); if( x == x1+1 ) /* edging */ gdImageLine( im, x-1, ypts[i].y2, x-1+xdepth, ypts[i].y2-ydepth, -ypts[i].slope<=depth_slope? ypts[i].shclr: ypts[i].lnclr ); } } FREE_ARRAY1( slope ); FREE_ARRAY1( lnclr ); FREE_ARRAY1( shclr ); FREE_ARRAY1( ypts ); } /* ------------------------------------------------------------------------- */ /* vals in pixels */ /* ref is front plane */ void draw_3d_area( gdImagePtr im, int x1, int x2, int y0, /* drawn from 0 */ int y1, int y2, int xdepth, int ydepth, int clr, int clrshd ) { gdPoint poly[4]; int y_intercept = 0; /* if xdepth || ydepth */ if( xdepth || ydepth ) { float line_slope = x2==x1? FLT_MAX: (float)-(y2-y1) / (float)(x2-x1); float depth_slope = xdepth==0? FLT_MAX: (float)ydepth/(float)xdepth; y_intercept = (y1 > y0 && y2 < y0) || /* line crosses y0 */ (y1 < y0 && y2 > y0)? (int)((1.0/ABS(line_slope))*(float)(ABS(y1-y0)))+x1: 0; /* never */ /* edging along y0 depth */ gdImageLine( im, x1+xdepth, y0-ydepth, x2+xdepth, y0-ydepth, clrshd ); SET_3D_POLY( poly, x1, x2, y1, y2, xdepth, ydepth ); /* top */ gdImageFilledPolygon( im, poly, 4, line_slope>depth_slope? clrshd: clr ); SET_3D_POLY( poly, x1, x2, y0, y0, xdepth, ydepth+1 ); /* along y axis */ gdImageFilledPolygon( im, poly, 4, clr ); SET_3D_POLY( poly, x2, x2, y0, y2, xdepth, ydepth ); /* side */ gdImageFilledPolygon( im, poly, 4, clrshd ); if( y_intercept ) gdImageLine( im, y_intercept, y0, y_intercept+xdepth, y0-ydepth, clrshd ); /* edging */ gdImageLine( im, x1, y0, x1+xdepth, y0-ydepth, clrshd ); /* edging */ gdImageLine( im, x2, y0, x2+xdepth, y0-ydepth, clrshd ); /* edging */ /* SET_3D_POLY( poly, x2, x2, y0, y2, xdepth, ydepth ); // side */ /* gdImageFilledPolygon( im, poly, 4, clrshd ); */ gdImageLine( im, x1, y1, x1+xdepth, y1-ydepth, clrshd ); /* edging */ gdImageLine( im, x2, y2, x2+xdepth, y2-ydepth, clrshd ); /* edging */ } if( y1 == y2 ) /* bar rect */ SET_RECT( poly, x1, x2, y0, y1 ); /* front */ else { poly[0].x = x1; poly[0].y = y0; poly[1].x = x2; poly[1].y = y0; poly[2].x = x2; poly[2].y = y2; poly[3].x = x1; poly[3].y = y1; } gdImageFilledPolygon( im, poly, 4, clr ); gdImageLine( im, x1, y0, x2, y0, clrshd ); /* edging along y0 */ if( (xdepth || ydepth) && /* front edging only on 3D */ (y1 y0 && y2 < y0 ) /* line crosses from below y0 */ gdImageLine( im, y_intercept, y0, x2, y2, clrshd ); else if( y1 < y0 && y2 > y0 ) /* line crosses from above y0 */ gdImageLine( im, x1, y1, y_intercept, y0, clrshd ); else /* completely above */ gdImageLine( im, x1, y1, x2, y2, clrshd ); } } /* ------------------------------------------------------------------------- */ /* vals in pixels */ /* ref is front plane */ void draw_3d_bar( gdImagePtr im, int x1, int x2, int y0, int yhigh, int xdepth, int ydepth, int clr, int clrshd ) { #define SET_3D_BAR( gdp, x1, x2, y1, y2, xoff, yoff ) \ gdp[0].x = x1, gdp[0].y = y1, \ gdp[1].x = x1+(xoff), gdp[1].y = y1-yoff, \ gdp[2].x = x2+(xoff), gdp[2].y = y2-yoff, \ gdp[3].x = x2, gdp[3].y = y2 gdPoint poly[4]; int usd = MIN( y0, yhigh ); /* up-side-down bars */ if( xdepth || ydepth ) { if( y0 != yhigh ) /* 0 height? */ { SET_3D_BAR( poly, x2, x2, y0, yhigh, xdepth, ydepth ); /* side */ gdImageFilledPolygon( im, poly, 4, clrshd ); } SET_3D_BAR( poly, x1, x2, usd, usd, xdepth, ydepth ); /* top */ gdImageFilledPolygon( im, poly, 4, clr ); } SET_RECT( poly, x1, x2, y0, yhigh ); /* front */ gdImageFilledPolygon( im, poly, 4, clr ); if( xdepth || ydepth ) gdImageLine( im, x1, usd, x2, usd, clrshd ); } /* ------------------------------------------------------------------------- */ struct BS { float y1; float y2; int clr; int shclr; }; static int barcmpr( const void *a, const void *b ) { if( ((struct BS*)a)->y2 < ((struct BS*)b)->y2 ) return -1; if( ((struct BS*)a)->y2 > ((struct BS*)b)->y2 ) return 1; return 0; } /* ------------------------------------------------------------------------- */ /* simple two-point linear interpolation */ /* attempts between first, then nearest */ void do_interpolations( int num_points, int interp_point, float vals[] ) { int i, j; float v1 = GDC_NOVALUE, v2 = GDC_NOVALUE; int p1 = -1, p2 = -1; /* find backwards */ for( i=interp_point-1; i>=0 && p1==-1; --i ) if( vals[i] != GDC_NOVALUE && vals[i] != GDC_INTERP_VALUE ) { v1 = vals[i]; p1 = i; } /* find forwards */ for( j=interp_point+1; j=0 && p2==-1; --i ) if( vals[i] != GDC_NOVALUE && vals[i] != GDC_INTERP_VALUE ) { v2 = vals[i]; p2 = i; } /* no backwards sample, find forwards */ for( ; j 1) */ float *combo_data ) /* only used on COMBO chart types */ { int i, j, k; int graphwidth; int grapheight; gdImagePtr im; gdImagePtr bg_img = NULL; float xorig, yorig, vyorig; float yscl = 0.0; float vyscl = 0.0; float xscl = 0.0; float vhighest = -FLT_MAX; float vlowest = FLT_MAX; float highest = -FLT_MAX; float lowest = FLT_MAX; gdPoint volpoly[4]; char do_vol = ( type == GDC_COMBO_HLC_BAR || /* aka: combo */ type == GDC_COMBO_HLC_AREA || type == GDC_COMBO_LINE_BAR || type == GDC_COMBO_LINE_AREA || type == GDC_COMBO_LINE_LINE || type == GDC_3DCOMBO_HLC_BAR || type == GDC_3DCOMBO_HLC_AREA|| type == GDC_3DCOMBO_LINE_BAR|| type == GDC_3DCOMBO_LINE_AREA || type == GDC_3DCOMBO_LINE_LINE ); char threeD = ( type == GDC_3DAREA || type == GDC_3DLINE || type == GDC_3DBAR || type == GDC_3DFLOATINGBAR || type == GDC_3DHILOCLOSE || type == GDC_3DCOMBO_HLC_BAR || type == GDC_3DCOMBO_HLC_AREA|| type == GDC_3DCOMBO_LINE_BAR|| type == GDC_3DCOMBO_LINE_AREA || type == GDC_3DCOMBO_LINE_LINE ); char num_groups = num_sets; /* set before num_sets gets adjusted */ char set_depth = ( GDC_stack_type == GDC_STACK_DEPTH )? num_groups: 1; char do_bar = ( type == GDC_3DBAR || /* offset X objects to leave */ type == GDC_BAR || /* room at X(0) and X(n) */ type == GDC_3DFLOATINGBAR || /* i.e., not up against Y axes */ type == GDC_FLOATINGBAR); char do_ylbl_fractions = /* %f format not given, or */ ( !GDC_ylabel_fmt || /* format doesn't have a %,g,e,E,f or F */ strlen(GDC_ylabel_fmt) == strcspn(GDC_ylabel_fmt,"%geEfF") ); float ylbl_interval = 0.0; int xlbl_hgt = 0; int xdepth_3Dtotal = 0; int ydepth_3Dtotal = 0; int xdepth_3D = 0; /* affects PX() */ int ydepth_3D = 0; /* affects PY() and PV() */ int hlf_barwdth = 0; /* half bar widths */ int hlf_hlccapwdth = 0; /* half cap widths for HLC_I_CAP and DIAMOND */ int annote_len = 0, annote_hgt = 0; /* args */ int setno = 0; /* affects PX() and PY() */ CREATE_ARRAY1( uvals, float *, type == GDC_HILOCLOSE || type == GDC_3DHILOCLOSE || type == GDC_3DCOMBO_HLC_BAR || type == GDC_3DCOMBO_HLC_AREA || type == GDC_COMBO_HLC_BAR || type == GDC_COMBO_HLC_AREA? num_sets *= 3: /* 1 more last set is vol */ type == GDC_FLOATINGBAR || type == GDC_3DFLOATINGBAR? num_sets *= 2: type == GDC_COMBO_LINE_BAR || type == GDC_3DCOMBO_LINE_BAR || type == GDC_3DCOMBO_LINE_AREA|| type == GDC_3DCOMBO_LINE_LINE|| type == GDC_COMBO_LINE_AREA || type == GDC_COMBO_LINE_LINE? num_sets: /* 1 more last set is vol */ num_sets ); CREATE_ARRAY1( ExtVolColor, int, num_points ); /* int ExtVolColor[num_points], */ CREATE_ARRAY2( ExtColor, int, num_sets, num_points ); /* ExtColor[num_sets][num_points], */ CREATE_ARRAY2( ExtColorShd, int, threeD?num_sets:1, /* ExtColorShd[num_sets][num_points]; */ threeD?num_points:1 ); /* shade colors only with 3D */ float *uvol; int BGColor, LineColor, PlotColor, GridColor, VolColor, ThumbDColor, ThumbLblColor, ThumbUColor, /* ArrowDColor, */ /* ArrowUColor, */ AnnoteColor; #ifdef HAVE_LIBFREETYPE char *gdc_title_font = GDC_title_font; /* for convienience */ char *gdc_ytitle_font = GDC_ytitle_font; /* in func calls */ char *gdc_xtitle_font = GDC_xtitle_font; /* char *gdc_yaxis_font = GDC_yaxis_font; */ char *gdc_xaxis_font = GDC_xaxis_font; double gdc_title_ptsize = GDC_title_ptsize; double gdc_ytitle_ptsize = GDC_ytitle_ptsize; double gdc_xtitle_ptsize = GDC_xtitle_ptsize; /* double gdc_yaxis_ptsize = GDC_yaxis_ptsize; */ double gdc_xaxis_ptsize = GDC_xaxis_ptsize; double gdc_xaxis_rad = TO_RAD( GDC_xaxis_angle ); char *gdc_annotation_font = GDC_annotation_font; double gdc_annotation_ptsize = GDC_annotation_ptsize; #else char *gdc_title_font = NULL; char *gdc_ytitle_font = NULL; char *gdc_xtitle_font = NULL; /* char *gdc_yaxis_font = NULL; */ char *gdc_xaxis_font = NULL; double gdc_title_ptsize = 0.0; double gdc_ytitle_ptsize = 0.0; double gdc_xtitle_ptsize = 0.0; /* double gdc_yaxis_ptsize = 0.0; */ double gdc_xaxis_ptsize = 0.0; double gdc_xaxis_rad = GDC_xaxis_angle==90.0? M_PI/2.0: 0.0; char *gdc_annotation_font = NULL; double gdc_annotation_ptsize=0.0; #endif double sin_xangle = 1.0, /* calc only when&if needed */ cos_xangle = 0.0; /* idiot checks */ if( IMGWIDTH<=0 || IMGHEIGHT<=0 || (!img_fptr && GDC_generate_img) ) { FREE_ARRAY1( uvals ); FREE_ARRAY1( ExtVolColor ); FREE_ARRAY2( ExtColor ); FREE_ARRAY2( ExtColorShd ); return -1; } if( num_points <= 0 ) { out_err( IMGWIDTH, IMGHEIGHT, img_fptr, GDC_BGColor, GDC_LineColor, "No Data Available" ); FREE_ARRAY1( uvals ); FREE_ARRAY1( ExtVolColor ); FREE_ARRAY2( ExtColor ); FREE_ARRAY2( ExtColorShd ); return 1; } load_font_conversions(); if( GDC_thumbnail ) { GDC_grid = FALSE; GDC_xaxis = FALSE; GDC_yaxis = FALSE; } /* ----- get args ----- */ for( i=0; ival, highest ); lowest = MIN( (GDC_scatter+i)->val, lowest ); } if( do_vol ) /* for now only one combo set allowed */ { /* vhighest = 1.0; */ /* vlowest = 0.0; */ for( j=0; j 0.0 ) vlowest = 0.0; /* bar, area should always start at 0 */ } if( lowest == FLT_MAX ) lowest = 0.0; if( highest == -FLT_MAX ) highest = 1.0; /* need a range */ if( type == GDC_AREA || /* bars and area should always start at 0 */ type == GDC_BAR || type == GDC_3DBAR || type == GDC_3DAREA ) if( highest < 0.0 ) highest = 0.0; else if( lowest > 0.0 ) /* negs should be drawn from 0 */ lowest = 0.0; if( GDC_requested_ymin != GDC_NOVALUE && GDC_requested_ymin < lowest ) lowest = GDC_requested_ymin; if( GDC_requested_ymax != GDC_NOVALUE && GDC_requested_ymax > highest ) highest = GDC_requested_ymax; /* ----- graph height and width within the img height width ----- */ /* grapheight/height is the actual size of the scalable graph */ { int title_hgt = GDC_title? 2 /* title? horizontal text line(s) */ + GDCfnt_sz(GDC_title,GDC_title_size,gdc_title_font,gdc_title_ptsize,0.0,NULL).h + 2: 2; int xlabel_hgt = 0; int xtitle_hgt = GDC_xtitle? 1+GDCfnt_sz(GDC_xtitle,GDC_xtitle_size,gdc_xtitle_font,gdc_xtitle_ptsize,0.0,NULL).h+1: 0; int ytitle_hgt = GDC_ytitle? 1+GDCfnt_sz(GDC_ytitle,GDC_ytitle_size,gdc_ytitle_font,gdc_ytitle_ptsize,M_PI/2.0,NULL).h+1: 0; int vtitle_hgt = do_vol&&GDC_ytitle2? 1+GDCfnt_sz(GDC_ytitle2,GDC_ytitle_size,gdc_ytitle_font,gdc_ytitle_ptsize,M_PI/2.0,NULL).h+1: 0; int ylabel_wth = 0; int vlabel_wth = 0; int xtics = GDC_ticks && (GDC_grid||GDC_xaxis)? 1+2: 0; int ytics = GDC_ticks && (GDC_grid||GDC_yaxis)? 1+3: 0; int vtics = GDC_ticks && (GDC_yaxis&&do_vol)? 3+1: 0; #define HYP_DEPTH ( (double)((IMGWIDTH+IMGHEIGHT)/2) * ((double)GDC_3d_depth)/100.0 ) #define RAD_DEPTH ( (double)GDC_3d_angle*2*M_PI/360 ) xdepth_3D = threeD? (int)( cos(RAD_DEPTH) * HYP_DEPTH ): 0; ydepth_3D = threeD? (int)( sin(RAD_DEPTH) * HYP_DEPTH ): 0; xdepth_3Dtotal = xdepth_3D*set_depth; ydepth_3Dtotal = ydepth_3D*set_depth; annote_hgt = GDC_annotation && *(GDC_annotation->note)? 1 + /* space to note */ (1+GDCfnt_sz( GDC_annotation->note,GDC_annotation_font_size, gdc_annotation_font,gdc_annotation_ptsize,0.0,NULL ).h) + 1 + /* space under note */ 2: 0; /* space to chart */ annote_len = GDC_annotation && *(GDC_annotation->note)? GDCfnt_sz( GDC_annotation->note,GDC_annotation_font_size, gdc_annotation_font,gdc_annotation_ptsize,0.0,NULL ).w: 0; /* find length of "longest" (Y) xaxis label */ /* find the average "width" (X) xaxis label */ /* avg method fails when 2 or 3 very wide are consecutive, with the rest being thin */ /* this is most evident with horizontal (0deg) xlabels */ /* assume in this case they are quite uniform, e.g., dates */ /* find affects on graphwidth/xorig of wildly overhanging angled labels */ if( GDC_xaxis && xlbl ) { int biggest = -INT_MAX, widest = -INT_MAX; #ifdef HAVE_LIBFREETYPE if( gdc_xaxis_rad!=M_PI/2.0 && gdc_xaxis_font && gdc_xaxis_ptsize ) { sin_xangle = sin( gdc_xaxis_rad ), cos_xangle = cos( gdc_xaxis_rad ); } #endif for( i=0; i ylbl_interval ) */ /* break; */ if( (highest-lowest)/ypoints[i] < ylbl_density_space_intvl ) break; /* gotta go through the above loop to catch the 'tweeners :-| */ } ylbl_interval = GDC_requested_yinterval != GDC_NOVALUE && GDC_requested_yinterval > ypoints[i-1]? GDC_requested_yinterval: ypoints[i-1]; /* perform floating point remainders */ /* gonculate largest interval-point < lowest */ if( lowest != 0.0 && lowest != GDC_requested_ymin ) { if( lowest < 0.0 ) lowest -= ylbl_interval; /* lowest = (lowest-ypoints[0]) - */ /* ( ( ((lowest-ypoints[0])/ylbl_interval)*ylbl_interval ) - */ /* ( (float)((int)((lowest-ypoints[0])/ylbl_interval))*ylbl_interval ) ); */ lowest = ylbl_interval * (float)(int)((lowest-ypoints[0])/ylbl_interval); } /* find smallest interval-point > highest */ tmp_highest = lowest; do /* while( (tmp_highest += ylbl_interval) <= highest ) */ { int nmrtr, dmntr, whole; char *price_to_str( float, int*, int*, int*, char* ); int lbl_len; char foo[32]; if( GDC_yaxis ) { /* XPG2 compatibility */ sprintf( foo, do_ylbl_fractions? "%.0f": GDC_ylabel_fmt, tmp_highest ); lbl_len = ylbl_interval<1.0? strlen( price_to_str(tmp_highest, &nmrtr, &dmntr, &whole, do_ylbl_fractions? NULL: GDC_ylabel_fmt) ): strlen( foo ); longest_ylblen = MAX( longest_ylblen, lbl_len ); } } while( (tmp_highest += ylbl_interval) <= highest ); ylabel_wth = longest_ylblen * GDC_fontc[GDC_yaxisfont_size].w; highest = GDC_requested_ymax==GDC_NOVALUE? tmp_highest: MAX( GDC_requested_ymax, highest ); if( do_vol ) { float num_yintrvls = (highest-lowest) / ylbl_interval; /* no skyscrapers */ if( vhighest != 0.0 ) vhighest += (vhighest-vlowest) / (num_yintrvls*2.0); if( vlowest != 0.0 ) vlowest -= (vhighest-vlowest) / (num_yintrvls*2.0); if( GDC_yaxis2 ) { char svlongest[32]; int lbl_len_low = sprintf( svlongest, GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f", vlowest ); int lbl_len_high = sprintf( svlongest, GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f", vhighest ); vlabel_wth = 1 + MAX( lbl_len_low,lbl_len_high ) * GDC_fontc[GDC_yaxisfont_size].w; } } } graphwidth = IMGWIDTH - ( ( (GDC_hard_size && GDC_hard_xorig)? GDC_hard_xorig: ( ytitle_hgt + ylabel_wth + ytics ) ) + vtics + vtitle_hgt + vlabel_wth + xdepth_3Dtotal ); if( GDC_hard_size && GDC_hard_graphwidth ) /* user wants to use his */ graphwidth = GDC_hard_graphwidth; GDC_hard_graphwidth = graphwidth; /* ----- scale to img size ----- */ /* offset to 0 at lower left (where it should be) */ xscl = (float)(graphwidth-xdepth_3Dtotal) / (float)(num_points + (do_bar?2:0)); yscl = -((float)grapheight) / (float)(highest-lowest); if( do_vol ) { float hilow_diff = vhighest-vlowest==0.0? 1.0: vhighest-vlowest; vyscl = -((float)grapheight) / hilow_diff; vyorig = (float)grapheight + ABS(vyscl) * MIN(vlowest,vhighest) + ydepth_3Dtotal + title_hgt + annote_hgt; } xorig = (float)( IMGWIDTH - ( graphwidth + vtitle_hgt + vtics + vlabel_wth ) ); if( GDC_hard_size && GDC_hard_xorig ) xorig = GDC_hard_xorig; GDC_hard_xorig = xorig; /* yorig = (float)grapheight + ABS(yscl * lowest) + ydepth_3Dtotal + title_hgt; */ yorig = (float)grapheight + ABS(yscl) * MIN(lowest,highest) + ydepth_3Dtotal + title_hgt + annote_hgt; /*???? if( GDC_hard_size && GDC_hard_yorig ) /* vyorig too? */ /*???? yorig = GDC_hard_yorig; FRED - check email */ GDC_hard_yorig = yorig; hlf_barwdth = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_bar_width/100.0)/2.0) ); /* used only for bars */ hlf_hlccapwdth = (int)( (float)(PX(2)-PX(1)) * (((float)GDC_HLC_cap_width/100.0)/2.0) ); } /* scaled, sized, ready */ /* ----- OK start the graphic ----- */ if( (GDC_hold_img & GDC_REUSE_IMAGE) && GDC_image != (void*)NULL ) im = GDC_image; else im = gdImageCreate( IMGWIDTH, IMGHEIGHT ); BGColor = gdImageColorAllocate( im, l2gdcal(GDC_BGColor) ); LineColor = clrallocate( im, GDC_LineColor ); PlotColor = clrallocate( im, GDC_PlotColor ); GridColor = clrallocate( im, GDC_GridColor ); if( do_vol ) { VolColor = clrallocate( im, GDC_VolColor ); for( i=0; icolor ); /* attempt to import optional background image */ if( GDC_BGImage ) { FILE *in = fopen(GDC_BGImage, "rb"); if( !in ) { ; /* Cant load background image, drop it */ } else { /* assume GIF */ /* should determine type by file extension, option, ... */ if( bg_img = gdImageCreateFromGif(in) ) /* = */ { int bgxpos = gdImageSX(bg_img) IMGWIDTH || /* resize only if too big */ gdImageSY(bg_img) > IMGHEIGHT ) /* [and center] */ { gdImageCopyResized( im, bg_img, /* dst, src */ bgxpos, bgypos, /* dstX, dstY */ 0, 0, /* srcX, srcY */ IMGWIDTH, IMGHEIGHT, /* dstW, dstH */ IMGWIDTH, IMGHEIGHT ); /* srcW, srcH */ } else /* just center */ gdImageCopy( im, bg_img, /* dst, src */ bgxpos, bgypos, /* dstX, dstY */ 0, 0, /* srcX, srcY */ IMGWIDTH, IMGHEIGHT ); /* W, H */ } fclose(in); } } for( j=0; j= 0.0 ) /* all pos plotting */ continue; else tmp_y = MIN( 0, highest ); /* step down to lowest */ if( i == 1 ) if( highest <= 0.0 ) /* all neg plotting */ continue; else tmp_y = MAX( 0, lowest ); /* step up to highest */ /* if( !(highest > 0 && lowest < 0) ) // doesn't straddle 0 */ /* { */ /* if( i == -1 ) // only do once: normal */ /* continue; */ /* } */ /* else */ /* tmp_y = 0; */ do /* while( (tmp_y (+-)= ylbl_interval) < [highest,lowest] ) */ { int n, d, w; char *price_to_str( float, int*, int*, int*, char* ); char nmrtr[3+1], dmntr[3+1], whole[8]; char all_whole = ylbl_interval<1.0? FALSE: TRUE; char *ylbl_str = price_to_str( tmp_y,&n,&d,&w, do_ylbl_fractions? NULL: GDC_ylabel_fmt ); if( do_ylbl_fractions ) { sprintf( nmrtr, "%d", n ); sprintf( dmntr, "%d", d ); sprintf( whole, "%d", w ); } if( GDC_grid || GDC_ticks ) { int x1, x2, y1, y2; /* int gridline_clr = tmp_y == 0.0? LineColor: GridColor; */ /* tics */ x1 = PX(0); y1 = PY(tmp_y); if( GDC_ticks ) gdImageLine( im, x1-2, y1, x1, y1, GridColor ); if( GDC_grid ) { setno = set_depth; x2 = PX(0); y2 = PY(tmp_y); /* w/ new setno */ gdImageLine( im, x1, y1, x2, y2, GridColor ); /* depth for 3Ds */ gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, GridColor ); setno = 0; /* set back to foremost */ } } if( GDC_yaxis ) if( do_ylbl_fractions ) { if( w || (!w && !n && !d) ) { gdImageString( im, GDC_fontc[GDC_yaxisfont_size].f, PX(0)-2-strlen(whole)*GDC_fontc[GDC_yaxisfont_size].w - ( (!all_whole)? (strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w + GDC_fontc[GDC_yaxisfont_size].w + strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w) : 1 ), PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2, (unsigned char*)whole, labelcolor ); } if( n ) { gdImageString( im, GDC_fontc[GDC_yaxisfont_size-1].f, PX(0)-2-strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w -GDC_fontc[GDC_yaxisfont_size].w -strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w + 1, PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2 + 1, (unsigned char*)nmrtr, labelcolor ); gdImageString( im, GDC_fontc[GDC_yaxisfont_size].f, PX(0)-2-GDC_fontc[GDC_yaxisfont_size].w -strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w, PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2, (unsigned char*)"/", labelcolor ); gdImageString( im, GDC_fontc[GDC_yaxisfont_size-1].f, PX(0)-2-strlen(nmrtr)*GDC_fontc[GDC_yaxisfont_size-1].w - 2, PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2 + 3, (unsigned char*)dmntr, labelcolor ); } } else gdImageString( im, GDC_fontc[GDC_yaxisfont_size].f, PX(0)-2-strlen(ylbl_str)*GDC_fontc[GDC_yaxisfont_size].w, PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2, (unsigned char*)ylbl_str, labelcolor ); if( do_vol && GDC_yaxis2 ) { char vylbl[16]; /* opposite of PV(y) */ sprintf( vylbl, GDC_ylabel2_fmt? GDC_ylabel2_fmt: "%.0f", ((float)(PY(tmp_y)+(setno*ydepth_3D)-vyorig))/vyscl ); setno = set_depth; if( GDC_ticks ) gdImageLine( im, PX(num_points-1+(do_bar?2:0)), PY(tmp_y), PX(num_points-1+(do_bar?2:0))+3, PY(tmp_y), GridColor ); if( atof(vylbl) == 0.0 ) /* rounding can cause -0 */ strcpy( vylbl, "0" ); gdImageString( im, GDC_fontc[GDC_yaxisfont_size].f, PX(num_points-1+(do_bar?2:0))+6, PY(tmp_y)-GDC_fontc[GDC_yaxisfont_size].h/2, (unsigned char*)vylbl, label2color ); setno = 0; } } while( ((i>0) && ((tmp_y += ylbl_interval) < highest)) || ((i<0) && ((tmp_y -= ylbl_interval) > lowest)) ); } /* catch last (bottom) grid line - specific to an "off" requested interval */ if( GDC_grid && threeD ) { setno = set_depth; gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), GridColor ); setno = 0; /* set back to foremost */ } /* vy axis title */ if( do_vol && GDC_ytitle2 ) { struct fnt_sz_t ytftsz = GDCfnt_sz( GDC_ytitle2, GDC_ytitle_size, gdc_ytitle_font, gdc_ytitle_ptsize, 0.0, NULL ); int titlecolor = GDC_YTitle2Color==GDC_DFLTCOLOR? VolColor: clrallocate( im, GDC_YTitle2Color ); GDCImageStringNL( im, &GDC_fontc[GDC_ytitle_size], gdc_ytitle_font, gdc_ytitle_ptsize, M_PI/2.0, IMGWIDTH-(1+ytftsz.h), yorig/2+ytftsz.w/2, GDC_ytitle2, titlecolor, GDC_JUSTIFY_CENTER, NULL ); } /* y axis title */ if( GDC_yaxis && GDC_ytitle ) { struct fnt_sz_t ytftsz = GDCfnt_sz( GDC_ytitle, GDC_ytitle_size, gdc_ytitle_font, gdc_ytitle_ptsize, 0.0, NULL ); int titlecolor = GDC_YTitleColor==GDC_DFLTCOLOR? PlotColor: clrallocate( im, GDC_YTitleColor ); GDCImageStringNL( im, &GDC_fontc[GDC_ytitle_size], gdc_ytitle_font, gdc_ytitle_ptsize, M_PI/2.0, 1, yorig/2+ytftsz.w/2, GDC_ytitle, titlecolor, GDC_JUSTIFY_CENTER, NULL ); } } /* interviening set grids */ /* 0 < setno < num_sets non-inclusive, they've already been covered */ if( GDC_grid && threeD ) { for( setno=set_depth - 1; setno > 0; --setno ) { gdImageLine( im, PX(0), PY(lowest), PX(0), PY(highest), GridColor ); gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), GridColor ); } setno = 0; } if( ( GDC_grid || GDC_0Shelf ) && /* line color grid at 0 */ ( (lowest < 0.0 && highest > 0.0) || ( (lowest == 0.0 || highest == 0.0) && !(GDC_border&GDC_BORDER_X) ) ) ) { int x1, x2, y1, y2; /* tics */ x1 = PX(0); y1 = PY(0); if( GDC_ticks ) gdImageLine( im, x1-2, y1, x1, y1, LineColor ); setno = set_depth; x2 = PX(0); y2 = PY(0); /* w/ new setno */ gdImageLine( im, x1, y1, x2, y2, LineColor ); /* depth for 3Ds */ gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), y2, LineColor ); setno = 0; /* set back to foremost */ } /* x ticks and xlables */ if( GDC_grid || GDC_xaxis ) { int num_xlbls = graphwidth / /* maximum x lables that'll fit */ ( (GDC_xlabel_spacing==SHRT_MAX?0:GDC_xlabel_spacing) + xlbl_hgt ); int labelcolor = GDC_XLabelColor==GDC_DFLTCOLOR? LineColor: clrallocate( im, GDC_XLabelColor ); for( i=0; i= num_points || GDC_xlabel_spacing == SHRT_MAX )) || (GDC_xlabel_ctl && xi>=0 && *(GDC_xlabel_ctl+xi)) ) { DO_TICK(x1,y1); /* labeled points tick & grid */ DO_GRID(x1,y1,x2,y2); if( !do_bar || (i>0 && xi0 ) { if( GDC_grid == GDC_TICK_POINTS ) /* --- GRID --- */ DO_GRID( x1, y1, x2, y2 ); else if( GDC_grid > GDC_TICK_NONE ) { int k; int xt; int prevx = PX(i-1); int intrv_dist = (x1-prevx)/(GDC_grid+1); DO_GRID( x1, y1, x2, y2 ); for( k=0, xt=prevx + intrv_dist; k GDC_TICK_NONE ) { int k; int xt; int prevx=PX(i-1); int intrv_dist = (x1-prevx)/(GDC_ticks+1); DO_TICK( x1, y1 ); for( k=0, xt=prevx + intrv_dist; kpoint+(do_bar?1:0)), y1 = PY(lowest); setno = set_depth; gdImageLine( im, x1, y1, PX(GDC_annotation->point+(do_bar?1:0)), PY(lowest), AnnoteColor ); gdImageLine( im, PX(GDC_annotation->point+(do_bar?1:0)), PY(lowest), PX(GDC_annotation->point+(do_bar?1:0)), PY(highest)-2, AnnoteColor ); setno = 0; } /* ---------- start plotting the data ---------- */ switch( type ) { case GDC_3DBAR: /* depth, width, y interval need to allow for whitespace between bars */ case GDC_BAR: /* --------- */ switch( GDC_stack_type ) { case GDC_STACK_DEPTH: for( setno=num_sets-1; setno>=0; --setno ) /* back sets first PX, PY depth */ for( i=0; i=0; --setno ) /* back sets first PX, PY depth */ for( i=0; i uvals[0+setno*2][i] ) draw_3d_bar( im, PX(i+(do_bar?1:0))-hlf_barwdth, PX(i+(do_bar?1:0))+hlf_barwdth, PY(uvals[0+setno*2][i]), PY(uvals[1+setno*2][i]), xdepth_3D, ydepth_3D, ExtColor[setno][i], threeD? ExtColorShd[setno][i]: ExtColor[setno][i] ); setno = 0; break; case GDC_STACK_BESIDE: { /* h/.5, h/1, h/1.5, h/2, ... */ int new_barwdth = (int)( (float)hlf_barwdth / ((float)num_groups/2.0) ); for( i=0; i uvals[0+j*2][i] ) draw_3d_bar( im, PX(i+(do_bar?1:0))-hlf_barwdth+new_barwdth*j+1, PX(i+(do_bar?1:0))-hlf_barwdth+new_barwdth*(j+1), PY(uvals[0+j*2][i]), PY(uvals[1+j*2][i]), xdepth_3D, ydepth_3D, ExtColor[j][i], threeD? ExtColorShd[j][i]: ExtColor[j][i] ); } break; } break; case GDC_LINE: case GDC_COMBO_LINE_BAR: case GDC_COMBO_LINE_AREA: case GDC_COMBO_LINE_LINE: for( j=num_sets-1; j>=0; --j ) for( i=1; i=0; --j ) if( uvals[j][i-1] != GDC_NOVALUE && uvals[j][i] != GDC_NOVALUE ) { setno = j; y1[j] = PY(uvals[j][i-1]); y2[j] = PY(uvals[j][i]); draw_3d_line( im, PY(0), PX(i-1), PX(i), &(y1[j]), &(y2[j]), xdepth_3D, ydepth_3D, 1, &(ExtColor[j][i]), &(ExtColorShd[j][i]) ); setno = 0; } } else if( GDC_stack_type == GDC_STACK_BESIDE || GDC_stack_type == GDC_STACK_SUM ) /* all same plane */ { int set; float usey1 = 0.0, usey2 = 0.0; for( j=0,set=0; j=0; --j ) /* back sets 1st (setno = 0) */ for( i=1; i=0; --setno ) /* back sets first PX, PY depth */ for( i=1; i=0; --j ) { for( i=1; i PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth) ) && uvals[HIGHSET+j*3][i-1] != GDC_NOVALUE ) if( GDC_HLC_style & GDC_HLC_I_CAP ) { SET_3D_POLY( poly, PX(i-1)-hlf_hlccapwdth, PX(i-1)+hlf_hlccapwdth, PY(uvals[HIGHSET+j*3][i-1]), PY(uvals[HIGHSET+j*3][i-1]), xdepth_3D, ydepth_3D ); gdImageFilledPolygon( im, poly, 4, ExtColor[HIGHSET+j*3][i-1] ); gdImagePolygon( im, poly, 4, ExtColorShd[HIGHSET+j*3][i-1] ); } if( i < num_points && uvals[CLOSESET+j*3][i] != GDC_NOVALUE ) { if( GDC_HLC_style & GDC_HLC_CLOSE_CONNECTED ) /* line from prev close */ { SET_3D_POLY( poly, PX(i-1), PX(i), PY(uvals[CLOSESET+j*3][i-1]), PY(uvals[CLOSESET+j*3][i-1]), xdepth_3D, ydepth_3D ); gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i] ); gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i] ); } else /* CLOSE_CONNECTED and CONNECTING are mutually exclusive */ if( GDC_HLC_style & GDC_HLC_CONNECTING ) /* thin connecting line */ { int y1 = PY(uvals[CLOSESET+j*3][i-1]), y2 = PY(uvals[CLOSESET+j*3][i]); draw_3d_line( im, PY(0), PX(i-1), PX(i), &y1, &y2, /* rem only 1 set */ xdepth_3D, ydepth_3D, 1, &(ExtColor[CLOSESET+j*3][i]), &(ExtColorShd[CLOSESET+j*3][i]) ); /* edge font of it */ gdImageLine( im, PX(i-1), PY(uvals[CLOSESET+j*3][i-1]), PX(i), PY(uvals[CLOSESET+j*3][i]), ExtColorShd[CLOSESET+j*3][i] ); } /* top half 'I' again */ if( PY(uvals[CLOSESET+j*3][i-1]) <= PY(uvals[CLOSESET+j*3][i]) && uvals[HIGHSET+j*3][i-1] != GDC_NOVALUE ) if( GDC_HLC_style & GDC_HLC_I_CAP ) { SET_3D_POLY( poly, PX(i-1)-hlf_hlccapwdth, PX(i-1)+hlf_hlccapwdth, PY(uvals[HIGHSET+j*3][i-1]), PY(uvals[HIGHSET+j*3][i-1]), xdepth_3D, ydepth_3D ); gdImageFilledPolygon( im, poly, 4, ExtColor[HIGHSET+j*3][i-1] ); gdImagePolygon( im, poly, 4, ExtColorShd[HIGHSET+j*3][i-1] ); } } if( GDC_HLC_style & GDC_HLC_DIAMOND ) { /* front */ poly[0].x = PX(i-1)-hlf_hlccapwdth; poly[0].y = PY(uvals[CLOSESET+j*3][i-1]); poly[1].x = PX(i-1); poly[1].y = PY(uvals[CLOSESET+j*3][i-1])+hlf_hlccapwdth; poly[2].x = PX(i-1)+hlf_hlccapwdth; poly[2].y = PY(uvals[CLOSESET+j*3][i-1]); poly[3].x = PX(i-1); poly[3].y = PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth; gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] ); gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] ); /* bottom side */ SET_3D_POLY( poly, PX(i-1), PX(i-1)+hlf_hlccapwdth, PY(uvals[CLOSESET+j*3][i-1])+hlf_hlccapwdth, PY(uvals[CLOSESET+j*3][i-1]), xdepth_3D, ydepth_3D ); gdImageFilledPolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] ); /* gdImagePolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] ); */ /* top side */ SET_3D_POLY( poly, PX(i-1), PX(i-1)+hlf_hlccapwdth, PY(uvals[CLOSESET+j*3][i-1])-hlf_hlccapwdth, PY(uvals[CLOSESET+j*3][i-1]), xdepth_3D, ydepth_3D ); gdImageFilledPolygon( im, poly, 4, ExtColor[CLOSESET+j*3][i-1] ); gdImagePolygon( im, poly, 4, ExtColorShd[CLOSESET+j*3][i-1] ); } } } } break; case GDC_HILOCLOSE: case GDC_COMBO_HLC_BAR: case GDC_COMBO_HLC_AREA: for( j=num_groups-1; j>=0; --j ) { for( i=0; iwidth)/100.0)/2.0) ); int scat_x = PX( (GDC_scatter+i)->point + (do_bar?1:0) ), scat_y = PY( (GDC_scatter+i)->val ); if( (GDC_scatter+i)->point >= num_points || /* invalid point */ (GDC_scatter+i)->point < 0 ) continue; scatter_clr[i] = clrallocate( im, (GDC_scatter+i)->color ); switch( (GDC_scatter+i)->ind ) { case GDC_SCATTER_CIRCLE: { long uniq_clr = get_uniq_color( im ); int s = 0, e = 360, fo = 0; if( !do_bar ) if( (GDC_scatter+i)->point == 0 ) { s = 270; e = 270+180; fo = 1; } else if( (GDC_scatter+i)->point == num_points-1 ) { s = 90; e = 90+180; fo = -1; } if( uniq_clr != -1L ) /* the safe way */ { int uc = gdImageColorAllocate( im, l2gdcal(uniq_clr) ); gdImageArc( im, scat_x, scat_y, hlf_scatterwdth*2, hlf_scatterwdth*2, s, e, uc ); if( fo ) /* close off semi-circle case */ gdImageLine( im, scat_x, scat_y+hlf_scatterwdth, scat_x, scat_y-hlf_scatterwdth, uc ); gdImageFillToBorder( im, scat_x+fo, scat_y, uc, scatter_clr[i] ); gdImageArc( im, scat_x, scat_y, hlf_scatterwdth*2, hlf_scatterwdth*2, s, e, scatter_clr[i] ); if( fo ) gdImageLine( im, scat_x, scat_y+hlf_scatterwdth, scat_x, scat_y-hlf_scatterwdth, scatter_clr[i] ); gdImageColorDeallocate( im, uc ); } else /* chance it */ { gdImageArc( im, scat_x, scat_y, hlf_scatterwdth*2, hlf_scatterwdth*2, s, e, scatter_clr[i] ); if( fo ) gdImageLine( im, scat_x, scat_y+hlf_scatterwdth, scat_x, scat_y-hlf_scatterwdth, scatter_clr[i] ); gdImageFillToBorder( im, scat_x+fo, scat_y, scatter_clr[i], scatter_clr[i] ); } } break; case GDC_SCATTER_TRIANGLE_UP: ct[0].x = scat_x; ct[0].y = scat_y; ct[1].x = scat_x - hlf_scatterwdth; ct[1].y = scat_y + hlf_scatterwdth;; ct[2].x = scat_x + hlf_scatterwdth; ct[2].y = scat_y + hlf_scatterwdth; if( !do_bar ) if( (GDC_scatter+i)->point == 0 ) ct[1].x = scat_x; else if( (GDC_scatter+i)->point == num_points-1 ) ct[2].x = scat_x; gdImageFilledPolygon( im, ct, 3, scatter_clr[i] ); break; case GDC_SCATTER_TRIANGLE_DOWN: ct[0].x = scat_x; ct[0].y = scat_y; ct[1].x = scat_x - hlf_scatterwdth; ct[1].y = scat_y - hlf_scatterwdth;; ct[2].x = scat_x + hlf_scatterwdth; ct[2].y = scat_y - hlf_scatterwdth; if( !do_bar ) if( (GDC_scatter+i)->point == 0 ) ct[1].x = scat_x; else if( (GDC_scatter+i)->point == num_points-1 ) ct[2].x = scat_x; gdImageFilledPolygon( im, ct, 3, scatter_clr[i] ); break; } } FREE_ARRAY1( scatter_clr ); } /* box it off */ /* after plotting so the outline covers any plot lines */ { if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_X) ) gdImageLine( im, PX(0), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(lowest), LineColor ); if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_TOP) ) { setno = set_depth; gdImageLine( im, PX(0), PY(highest), PX(num_points-1+(do_bar?2:0)), PY(highest), LineColor ); setno = 0; } } if( GDC_border ) { int x1, y1, x2, y2; x1 = PX(0); y1 = PY(highest); x2 = PX(num_points-1+(do_bar?2:0)); y2 = PY(lowest); if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_Y) ) gdImageLine( im, x1, PY(lowest), x1, y1, LineColor ); setno = set_depth; if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_Y) || (GDC_border & GDC_BORDER_TOP) ) gdImageLine( im, x1, y1, PX(0), PY(highest), LineColor ); /* if( !GDC_grid || do_vol || GDC_thumbnail ) // grid leaves right side Y open */ { if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_X) || (GDC_border & GDC_BORDER_Y2) ) gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), PY(lowest), LineColor ); if( GDC_border == GDC_BORDER_ALL || (GDC_border & GDC_BORDER_Y2) ) gdImageLine( im, PX(num_points-1+(do_bar?2:0)), PY(lowest), PX(num_points-1+(do_bar?2:0)), PY(highest), LineColor ); } setno = 0; } if( GDC_0Shelf && threeD && /* front of 0 shelf */ ( (lowest < 0.0 && highest > 0.0) || ( (lowest == 0.0 || highest == 0.0) && !(GDC_border&GDC_BORDER_X) ) ) ) { int x2 = PX( num_points-1+(do_bar?2:0) ), y2 = PY( 0 ); gdImageLine( im, PX(0), PY(0), x2, y2, LineColor ); /* front line */ setno = set_depth; /* depth for 3Ds */ gdImageLine( im, x2, y2, PX(num_points-1+(do_bar?2:0)), PY(0), LineColor ); setno = 0; /* set back to foremost */ } if( GDC_annotation ) /* front half of annotation line */ { int x1 = PX(GDC_annotation->point+(do_bar?1:0)), y1 = PY(highest); int x2; /* front line */ gdImageLine( im, x1, PY(lowest)+1, x1, y1, AnnoteColor ); if( threeD ) { /* on back plane */ setno = set_depth; x2 = PX(GDC_annotation->point+(do_bar?1:0)); /* prspective line */ gdImageLine( im, x1, y1, x2, PY(highest), AnnoteColor ); } else /* for 3D done with back line */ { x2 = PX(GDC_annotation->point+(do_bar?1:0)); gdImageLine( im, x1, y1, x1, y1-2, AnnoteColor ); } /* line-to and note */ if( *(GDC_annotation->note) ) /* any note? */ { if( GDC_annotation->point >= (num_points/2) ) /* note to the left */ { gdImageLine( im, x2, PY(highest)-2, x2-annote_hgt/2, PY(highest)-2-annote_hgt/2, AnnoteColor ); GDCImageStringNL( im, &GDC_fontc[GDC_annotation_font_size], gdc_annotation_font, gdc_annotation_ptsize, 0.0, x2-annote_hgt/2-1-annote_len - 1, PY(highest)-annote_hgt+1, GDC_annotation->note, AnnoteColor, GDC_JUSTIFY_RIGHT, NULL ); } else /* note to right */ { gdImageLine( im, x2, PY(highest)-2, x2+annote_hgt/2, PY(highest)-2-annote_hgt/2, AnnoteColor ); GDCImageStringNL( im, &GDC_fontc[GDC_annotation_font_size], gdc_annotation_font, gdc_annotation_ptsize, 0.0, x2+annote_hgt/2+1 + 1, PY(highest)-annote_hgt+1, GDC_annotation->note, AnnoteColor, GDC_JUSTIFY_LEFT, NULL ); } } setno = 0; } /* usually GDC_generate_img is used in conjunction with hard or hold options */ if( GDC_generate_img ) { fflush(img_fptr); /* clear anything buffered */ switch( GDC_image_type ) { #ifdef HAVE_JPEG case GDC_JPEG: gdImageJpeg( im, img_fptr, GDC_jpeg_quality ); break; #endif case GDC_WBMP: gdImageWBMP( im, PlotColor, img_fptr ); break; case GDC_GIF: gdImageGif( im, img_fptr); break; case GDC_PNG: default: gdImagePng( im, img_fptr ); } } if( bg_img ) gdImageDestroy(bg_img); if( GDC_hold_img & GDC_EXPOSE_IMAGE ) GDC_image = (void*)im; else gdImageDestroy(im); FREE_ARRAY1( uvals ); FREE_ARRAY1( ExtVolColor ); FREE_ARRAY2( ExtColor ); FREE_ARRAY2( ExtColorShd ); return 0; } gdchart0.11.5dev/gdchart.h0000644000175000001440000002303310160620637016071 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev GDCHART.H 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ #ifndef _GDCHART_H #define _GDCHART_H #ifndef _GDC_H #include "gdc.h" #endif #define MAX_NOTE_LEN 19 #define GDC_INTERP_VALUE (GDC_NOVALUE/2.0) /* must set GDC_interpolations */ #define GDC_INTERP ((GDC_interpolations=TRUE),GDC_INTERP_VALUE) typedef enum { GDC_LINE, GDC_AREA, GDC_BAR, GDC_FLOATINGBAR, GDC_HILOCLOSE, GDC_COMBO_LINE_BAR, /* aka, VOL[ume] */ GDC_COMBO_HLC_BAR, GDC_COMBO_LINE_AREA, GDC_COMBO_LINE_LINE, GDC_COMBO_HLC_AREA, GDC_3DHILOCLOSE, GDC_3DCOMBO_LINE_BAR, GDC_3DCOMBO_LINE_AREA, GDC_3DCOMBO_LINE_LINE, GDC_3DCOMBO_HLC_BAR, GDC_3DCOMBO_HLC_AREA, GDC_3DBAR, GDC_3DFLOATINGBAR, GDC_3DAREA, GDC_3DLINE } GDC_CHART_T; typedef enum { GDC_STACK_DEPTH, /* "behind" (even non-3D) */ GDC_STACK_SUM, GDC_STACK_BESIDE, GDC_STACK_LAYER } GDC_STACK_T; /* applies only to num_lines > 1 */ typedef enum { GDC_HLC_DIAMOND = 1, GDC_HLC_CLOSE_CONNECTED = 2, /* can't be used w/ CONNECTING */ GDC_HLC_CONNECTING = 4, /* can't be used w/ CLOSE_CONNECTED */ GDC_HLC_I_CAP = 8 } GDC_HLC_STYLE_T; /* can be OR'd */ /* only 1 annotation allowed */ typedef struct { float point; /* 0 <= point < num_points */ unsigned long color; char note[MAX_NOTE_LEN+1]; /* NLs ok here */ } GDC_ANNOTATION_T; typedef enum { GDC_SCATTER_TRIANGLE_DOWN, GDC_SCATTER_TRIANGLE_UP, GDC_SCATTER_CIRCLE } GDC_SCATTER_IND_T; typedef struct { float point; /* 0 <= point < num_points */ float val; unsigned short width; /* % (1-100) */ unsigned long color; GDC_SCATTER_IND_T ind; } GDC_SCATTER_T; typedef enum { GDC_TICK_LABELS = -2, /* only at labels */ GDC_TICK_POINTS = -1, /* each num_points */ GDC_TICK_NONE = 0 /* > GDC_TICK_NONE */ /* points & inter-point */ } GDC_TICK_T; typedef enum { /* backward compatible w/ FALSE/TRUE */ GDC_BORDER_NONE = 0, GDC_BORDER_ALL = 1, /* should be GDC_BORDER_Y|Y2|X|TOP */ GDC_BORDER_X = 2, GDC_BORDER_Y = 4, GDC_BORDER_Y2 = 8, GDC_BORDER_TOP = 16 } GDC_BORDER_T; /****************************************************/ /********** USER CHART OPTIONS w/ defaults **********/ /****************************************************/ EXTERND char *GDC_ytitle; EXTERND char *GDC_xtitle; EXTERND char *GDC_ytitle2; /* ostesibly: volume label */ EXTERND char *GDC_title; /* NLs ok here */ EXTERND enum GDC_font_size GDC_title_size DEFAULTO( GDC_MEDBOLD ); EXTERND enum GDC_font_size GDC_ytitle_size DEFAULTO( GDC_MEDBOLD ); EXTERND enum GDC_font_size GDC_xtitle_size DEFAULTO( GDC_MEDBOLD ); EXTERND enum GDC_font_size GDC_yaxisfont_size DEFAULTO( GDC_SMALL ); EXTERND enum GDC_font_size GDC_xaxisfont_size DEFAULTO( GDC_SMALL ); EXTERND double GDC_xaxis_angle DEFAULTO( 90.0 ); /* 0,90. FT: 0-90 */ #ifdef HAVE_LIBFREETYPE EXTERND char *GDC_title_font DEFAULTO( NULL ); EXTERND char *GDC_ytitle_font DEFAULTO( NULL ); EXTERND char *GDC_xtitle_font DEFAULTO( NULL ); EXTERND char *GDC_yaxis_font DEFAULTO( NULL ); EXTERND char *GDC_xaxis_font DEFAULTO( NULL ); EXTERND double GDC_title_ptsize DEFAULTO( 0.0 ); EXTERND double GDC_ytitle_ptsize DEFAULTO( 0.0 ); EXTERND double GDC_xtitle_ptsize DEFAULTO( 0.0 ); EXTERND double GDC_yaxis_ptsize DEFAULTO( 0.0 ); EXTERND double GDC_xaxis_ptsize DEFAULTO( 0.0 ); #endif EXTERND char *GDC_ylabel_fmt DEFAULTO( NULL ); /* printf fmt'ing, e.g.: "%.2f" */ EXTERND char *GDC_ylabel2_fmt DEFAULTO( NULL ); /* default: "%.0f" future: fractions */ EXTERND char *GDC_xlabel_ctl DEFAULTO( NULL ); /* num_points[] TRUE,FALSE */ EXTERND short GDC_xlabel_spacing DEFAULTO( 5 ); /* pixels SHRT_MAX means force all */ EXTERND char GDC_ylabel_density DEFAULTO( 80 ); /* % */ EXTERND char GDC_interpolations DEFAULTO( FALSE ); /* GDC_INTERP_VALUE in data */ EXTERND float GDC_requested_ymin DEFAULTO( GDC_NOVALUE ); EXTERND float GDC_requested_ymax DEFAULTO( GDC_NOVALUE ); EXTERND float GDC_requested_yinterval DEFAULTO( GDC_NOVALUE ); EXTERND char GDC_0Shelf DEFAULTO( TRUE ); /* if applicable */ EXTERND GDC_TICK_T GDC_grid DEFAULTO( GDC_TICK_LABELS ); EXTERND GDC_TICK_T GDC_ticks DEFAULTO( GDC_TICK_LABELS ); EXTERND char GDC_xaxis DEFAULTO( TRUE ); EXTERND char GDC_yaxis DEFAULTO( TRUE ); EXTERND char GDC_yaxis2 DEFAULTO( TRUE ); EXTERND char GDC_yval_style DEFAULTO( TRUE ); EXTERND GDC_STACK_T GDC_stack_type DEFAULTO( GDC_STACK_DEPTH ); EXTERND float GDC_3d_depth DEFAULTO( 5.0 ); /* % img size */ EXTERND unsigned char GDC_3d_angle DEFAULTO( 45 ); /* 1-89 */ EXTERND unsigned char GDC_bar_width DEFAULTO( 75 ); /* % (1-100) */ EXTERND GDC_HLC_STYLE_T GDC_HLC_style DEFAULTO( GDC_HLC_CLOSE_CONNECTED ); EXTERND unsigned char GDC_HLC_cap_width DEFAULTO( 25 ); /* % (1-100) */ EXTERND GDC_ANNOTATION_T *GDC_annotation DEFAULTO( (GDC_ANNOTATION_T*)NULL ); EXTERND enum GDC_font_size GDC_annotation_font_size DEFAULTO( GDC_SMALL ); #ifdef HAVE_LIBFREETYPE EXTERND char *GDC_annotation_font DEFAULTO( NULL ); EXTERND double GDC_annotation_ptsize DEFAULTO( 0.0 ); #endif EXTERND int GDC_num_scatter_pts DEFAULTO( 0 ); EXTERND GDC_SCATTER_T *GDC_scatter DEFAULTO( (GDC_SCATTER_T*)NULL ); EXTERND char GDC_thumbnail DEFAULTO( FALSE ); EXTERND char *GDC_thumblabel; EXTERND float GDC_thumbval DEFAULTO( -FLT_MAX ); EXTERND GDC_BORDER_T GDC_border DEFAULTO( GDC_BORDER_ALL ); EXTERND unsigned long GDC_BGColor DEFAULTO( 0x000000L ); /* black */ EXTERND unsigned long GDC_GridColor DEFAULTO( 0xA0A0A0L ); /* gray */ EXTERND unsigned long GDC_LineColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_PlotColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_VolColor DEFAULTO( 0xA0A0FFL ); /* lgtblue1 */ EXTERND unsigned long GDC_TitleColor DEFAULTO( GDC_DFLTCOLOR ); /* "opposite" of BG */ EXTERND unsigned long GDC_XTitleColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_YTitleColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_YTitle2Color DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_XLabelColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_YLabelColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDC_YLabel2Color DEFAULTO( GDC_DFLTCOLOR ); /* supercedes VolColor ulong_color[num_points] */ EXTERND unsigned long *GDC_ExtVolColor DEFAULTO( (unsigned long*)NULL ); /* supercedes LineColor ulong_color[num_sets] */ EXTERND unsigned long *GDC_SetColor DEFAULTO( (unsigned long*)NULL ); /* supercedes SetColor ulong_color[num_sets][num_points] */ EXTERND unsigned long *GDC_ExtColor DEFAULTO( (unsigned long*)NULL ); EXTERND char GDC_transparent_bg DEFAULTO( FALSE ); EXTERND char *GDC_BGImage DEFAULTO( (char*)NULL ); /* legends? separate img? */ /* auto-size fonts, based on image size? */ /* ----- following options are for expert users only ----- */ /* for alignment of multiple charts */ /* USE WITH CAUTION! */ EXTERND char GDC_hard_size DEFAULTO( FALSE ); EXTERND int GDC_hard_xorig DEFAULTO( 0 ); /* in/out */ EXTERND int GDC_hard_graphwidth DEFAULTO( 0 ); /* in/out */ EXTERND int GDC_hard_yorig DEFAULTO( 0 ); /* in/out */ EXTERND int GDC_hard_grapheight DEFAULTO( 0 ); /* in/out */ /**** COMMON OPTIONS ********************************/ /* NOTE: common options copy here for reference only! */ /* they live in gdc.h */ #ifndef _GDC_COMMON_OPTIONS #define _GDC_COMMON_OPTIONS EXTERND char GDC_generate_img DEFAULTO( TRUE ); EXTERND GDC_HOLD_IMAGE_T GDC_hold_img DEFAULTO( GDC_DESTROY_IMAGE ); EXTERND void *GDC_image DEFAULTO( (void*)NULL ); /* in/out */ #endif /****************************************************/ #ifdef GDC_LIB #define clrallocate( im, rawclr ) _clrallocate( im, rawclr, GDC_BGColor ) #define clrshdallocate( im, rawclr ) _clrshdallocate( im, rawclr, GDC_BGColor ) #endif int GDC_out_graph( short IMGWIDTH, /* no check for a image that's too small to fit */ short IMGHEIGHT, FILE *img_fptr, /* open file pointer (iamge out) stdout ok */ GDC_CHART_T type, int num_points, /* points along x axis (even iterval) */ /* all arrays dependant on this */ char *xlbl[], /* array of xlabels */ int num_sets, float *data, /* based on num_sets X num_points */ float *combo_data ); /* only used on COMBO chart types */ /* ----- backward compatible var arg interface ----- */ int out_graph( short imgwidth, short imgheight, FILE *img_fptr, /* open file pointer (image out) */ GDC_CHART_T type, int num_points, /* points along x axis (even iterval) */ char *xlbl[], int num_sets, ... ); /* expected params (...) for each chart type: GDC_LINE GDC_BAR GDC_3DBAR GDC_3DAREA GDC_AREA float vals[], ... multiple sets make sense for rest? GDC_HILOCLOSE float high[], float low[], float close[] GDC_COMBO_LINE_BAR GDC_COMBO_LINE_AREA float val[], float vol[] GDC_COMBO_HLC_BAR GDC_COMBO_HLC_AREA float high[], float low[], float close[], float vol[] */ /* Notes: GDC_thumbnail = TRUE is equivelent to: GDC_grid = FALSE GDC_xaxis = FALSE GDC_yaxis = FALSE */ #endif /*!_GDCHART_H*/ gdchart0.11.5dev/gdcpie.h0000644000175000001440000000635610160620644015717 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev GDCHART.H 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ #ifndef _GDCPIE_H #define _GDCPIE_H #ifndef _GDC_H #include "gdc.h" #endif #ifdef GDC_LIB extern struct GDC_FONT_T GDC_fontc[]; #endif typedef enum { GDC_3DPIE, GDC_2DPIE } GDCPIE_TYPE; typedef enum { GDCPIE_PCT_NONE, GDCPIE_PCT_ABOVE, /* relative to label, if any */ GDCPIE_PCT_BELOW, GDCPIE_PCT_RIGHT, GDCPIE_PCT_LEFT } GDCPIE_PCT_TYPE; /**************************************************/ /**** USER DEFINABLE PIE OPTIONS w/ defaults *****/ /**************************************************/ EXTERND unsigned long GDCPIE_BGColor DEFAULTO( 0x000000L ); /* black */ EXTERND unsigned long GDCPIE_PlotColor DEFAULTO( 0xC0C0C0L ); /* gray */ EXTERND unsigned long GDCPIE_LineColor DEFAULTO( GDC_DFLTCOLOR ); EXTERND unsigned long GDCPIE_EdgeColor DEFAULTO( GDC_NOCOLOR ); /* edging on/off */ EXTERND char GDCPIE_other_threshold DEFAULTO( -1 ); EXTERND unsigned short GDCPIE_3d_angle DEFAULTO( 45 ); /* 0-360 */ EXTERND unsigned short GDCPIE_3d_depth DEFAULTO( 10 ); /* % image width */ EXTERND unsigned short GDCPIE_perspective DEFAULTO( 0 ); /* % view */ EXTERND char *GDCPIE_title DEFAULTO( NULL ); /* NLs ok here */ EXTERND enum GDC_font_size GDCPIE_title_size DEFAULTO( GDC_MEDBOLD ); EXTERND enum GDC_font_size GDCPIE_label_size DEFAULTO( GDC_SMALL ); #ifdef HAVE_LIBFREETYPE EXTERND char *GDCPIE_title_font DEFAULTO( NULL ); EXTERND char *GDCPIE_label_font DEFAULTO( NULL ); EXTERND double GDCPIE_title_ptsize DEFAULTO( 0.0 ); EXTERND double GDCPIE_label_ptsize DEFAULTO( 0.0 ); #endif EXTERND int GDCPIE_label_dist DEFAULTO( 1+8/2 ); /* 1+GDC_fontc[GDCPIE_label_size].h/2 */ EXTERND unsigned char GDCPIE_label_line DEFAULTO( FALSE ); /* from label to slice */ EXTERND int *GDCPIE_explode DEFAULTO( (int*)NULL ); /* [num_points] */ /* [num_points] supercedes GDCPIE_PlotColor */ EXTERND unsigned long *GDCPIE_Color DEFAULTO( (unsigned long*)NULL ); EXTERND unsigned char *GDCPIE_missing DEFAULTO( (unsigned char*)NULL ); /* TRUE/FALSE */ EXTERND GDCPIE_PCT_TYPE GDCPIE_percent_labels DEFAULTO( GDCPIE_PCT_NONE ); EXTERND char *GDCPIE_percent_fmt DEFAULTO( "%.0f%%" ); /* printf fmt'ing */ /**** COMMON OPTIONS ******************************/ /* NOTE: common options copy here for reference only! */ /* they live in gdc.h */ #ifndef _GDC_COMMON_OPTIONS #define _GDC_COMMON_OPTIONS EXTERND char GDC_generate_img DEFAULTO( TRUE ); EXTERND GDC_HOLD_IMAGE_T GDC_hold_img DEFAULTO( GDC_DESTROY_IMAGE ); EXTERND void *GDC_image DEFAULTO( (void*)NULL ); /* in/out */ #endif /**************************************************/ #ifdef GDC_LIB #define clrallocate( im, rawclr ) _clrallocate( im, rawclr, GDCPIE_BGColor ) #define clrshdallocate( im, rawclr ) _clrshdallocate( im, rawclr, GDCPIE_BGColor ) #endif void GDC_out_pie( short width, short height, FILE*, /* open file pointer, can be stdout */ GDCPIE_TYPE, int num_points, char *labels[], /* slice labels */ float data[] ); #endif /*!_GDCPIE_H*/ gdchart0.11.5dev/price_conv.c0000644000175000001440000000422510160620655016601 0ustar ubverdusers00000000000000/* GDCHART 0.10.0dev PRICE_CONV.C 2 Nov 2000 */ /* Copyright Bruce Verderaime 1998-2004 */ /* * - price as float to a string (ostensibly for printing) */ #include #include #include #include /* ----------------------------------------------------------------- */ /* -- convert a float to a printable string, in form: -- */ /* -- W N/D -- */ /* -- where W is whole, N is numerator, D is denominator -- */ /* -- the frac N/D is one of 2nds, 4,8,16,32,64,128,256ths -- */ /* -- if cannot convert, return str of the float -- */ /* ----------------------------------------------------------------- */ #define EPSILON ((1.0/256.0)/2.0) #define GET_DEC(x) ( (x) - (float)(int)(x) ) char* price_to_str( float price, int *numorator, int *demoninator, int *decimal, char *fltfmt ) /* printf fmt'ing str */ { static char rtn[64]; int whole = (int)price; float dec = GET_DEC( price ), numr; /* float pow( double, double ); */ /* caller doesn't want fractions */ if( fltfmt ) { sprintf( rtn, fltfmt, price ); *numorator = *demoninator = *decimal = 0; return rtn; } numr = dec * 256; /* check if we have a perfect fration in 256ths */ { float rdec = GET_DEC( numr ); if( rdec < EPSILON ) ; /* close enough to frac */ else if( (1-rdec) < EPSILON ) /* just over but close enough */ ++numr; else /* no frac match */ { sprintf( rtn, "%f", price ); *numorator = *demoninator = *decimal = 0; return rtn; } } /* now have numr 256ths */ /* resolve down */ if( numr != 0 ) { int cnt = 8; while( (float)(numr)/2.0 == (float)(int)(numr/2) ) { numr /= 2; --cnt; } /* don't want both whole AND numerator to be - */ if( whole<0 && numr<0.0 ) numr = -numr; *numorator = (int)numr; *demoninator = (int)pow(2.0, (float)cnt); *decimal = whole; sprintf( rtn, "%d %d/%d", whole, (int)numr, *demoninator ); } else { *numorator = *demoninator = 0; *decimal = whole; sprintf( rtn, "%d", whole ); } return rtn; } gdchart0.11.5dev/ft_samp.sav0000644000175000001440000000570610160622566016462 0ustar ubverdusers00000000000000/* GDCHART 0.11.1b 3D Bar sample 17 June 2001 */ /* NOTE: fonts and locations specified are machine specific */ /* should be able to set font-search-path env GDFONTPATH */ /* see libgd documentation */ /* will default to builtin font, if specified TTF not found */ #include #include "gdc.h" #include "gdchart.h" #define NUM_SETS 1 #define NUM_POINTS 4 main() { float data [ NUM_SETS ][ NUM_POINTS ]; unsigned long extclr[ NUM_SETS ][ NUM_POINTS ]; char *lbls[] = { "angle - 45", "font - zirkle", "ptsz - 10", "Color - blue", "" }; get_data( data, 0, 500 ); get_individual_colors( extclr ); GDC_BGColor = 0xFFFFFF; GDC_PlotColor = 0x4080FF; GDC_ExtColor = &(extclr[0][0]); /* set color option */ GDC_title = "GDC_title\r\n(benjamingothic 12)"; GDC_title_font = "/usr/share/enlightenment/E-docs/benjamingothic.ttf"; GDC_title_ptsize = 12; GDC_xtitle = "GDC_xtitle\r\n(x-files 12)"; GDC_xtitle_font = "/usr/share/enlightenment/E-docs/x-files.ttf"; GDC_xtitle_ptsize = 12; GDC_ytitle = "GDC_ytitle\r\n(times 10 i)"; GDC_ytitle_font = "/dos/C/windows/fonts/timesi.ttf"; GDC_ytitle_ptsize = 10; GDC_xaxis_angle = 45.0; GDC_xaxis_font = "/usr/share/enlightenment/themes/DEFAULT/ttfonts/zirkle.ttf"; GDC_xaxis_ptsize = 11.0; GDC_XLabelColor = 0x000080; GDC_bar_width = 60; /* (%) */ GDC_image_type = GDC_PNG; /* ---- call the lib V0.95b ----- */ GDC_out_graph( 400, 300, /* width, height */ stdout, /* open FILE pointer */ GDC_3DBAR, /* chart type */ NUM_POINTS, /* num points per data set */ lbls, /* X labels array of char* */ 1, /* number of data sets */ (float*)data, /* data */ (float*)NULL ); /* no right-hand-axis data */ exit(0); } /* --------------------------------------------------------- */ /* sample data gathering routine */ /* data can come from anywhere, generally a DB or data file */ /* here it's randomly generated */ /* --------------------------------------------------------- */ #include /* for rand() */ #include /* for seed */ get_data( float data[NUM_SETS][NUM_POINTS], int low, int high ) { int i, j; srand( (unsigned int)time((time_t)NULL) ); for( i=0; i