gdcpie.cpp File Reference

#include <stdio.h>
#include <values.h>
#include <math.h>
#include "gdc.h"
#include "gdcpie.h"
#include <string.h>
#include <stdlib.h>

Go to the source code of this file.

Data Structures

struct  tmp_slice_t

Defines

#define GDC_INCL
#define GDC_LIB
#define SET_RECT(gdp, x1, x2, y1, y2)
#define PX(x)   ( cx + (int)( ((float)rad)*sin(pscl*(double)(x)) ) )
#define PY(x)   ( cy - (int)( ((float)rad)*cos(pscl*(double)(x)) ) )
#define CX(i, d)
#define CY(i, d)
#define IX(i, f, d)   ( CX(i,d) + (int)( (double)rad * sin((double)(slice_angle[f][i])) ) )
#define IY(i, f, d)   ( CY(i,d) - (int)( (double)rad * cos((double)(slice_angle[f][i])) ) )
#define OX(i, o, d)   ( CX(i,d) + (int)( (double)rad * sin((double)(o)) ) )
#define OY(i, o, d)   ( CY(i,d) - (int)( (double)rad * 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) )
#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) )
#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) )

Functions

static int ocmpr (const void *a1, const void *b1)
void pie_gif (short GIFWIDTH, short GIFHEIGHT, FILE *gif_fptr, GDCPIE_TYPE type, int num_points, char **lbl, float *val)
void hola ()

Variables

GDC_FONT_T GDC_fontc []
static float pie_3D_rad
static float dist_foo1
static float dist_foo2


Define Documentation

#define CX ( i,
 ) 

Value:

( cx                +   \
                                                  (d? xdepth_3D: 0) +   \
                                                  (int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * sin((double)(slice_angle[0][i])) ) )

Definition at line 51 of file gdcpie.cpp.

Referenced by pie_gif().

#define CY ( i,
 ) 

Value:

( cy                -   \
                                                  (d? ydepth_3D: 0) -   \
                                                  (int)( (double)(GDCPIE_explode?GDCPIE_explode[(i)]:0) * cos((double)(slice_angle[0][i])) ) )

Definition at line 54 of file gdcpie.cpp.

Referenced by pie_gif().

#define GDC_INCL

Definition at line 7 of file gdcpie.cpp.

#define GDC_LIB

Definition at line 8 of file gdcpie.cpp.

#define IX ( i,
f,
 )     ( CX(i,d) + (int)( (double)rad * sin((double)(slice_angle[f][i])) ) )

Definition at line 64 of file gdcpie.cpp.

Referenced by pie_gif().

#define IY ( i,
f,
 )     ( CY(i,d) - (int)( (double)rad * cos((double)(slice_angle[f][i])) ) )

Definition at line 65 of file gdcpie.cpp.

Referenced by pie_gif().

#define MOD_2PI (  )     ( (o)>=(2.0*M_PI)? ((o)-(2.0*M_PI)): (((o)<0)? ((o)+(2.0*M_PI)): (o)) )

Definition at line 75 of file gdcpie.cpp.

Referenced by pie_gif().

#define MOD_360 (  )     ( (o)>=360? (o)-360: (o) )

Definition at line 76 of file gdcpie.cpp.

#define OX ( i,
o,
 )     ( CX(i,d) + (int)( (double)rad * sin((double)(o)) ) )

Definition at line 67 of file gdcpie.cpp.

Referenced by pie_gif().

#define OY ( i,
o,
 )     ( CY(i,d) - (int)( (double)rad * cos((double)(o)) ) )

Definition at line 68 of file gdcpie.cpp.

Referenced by pie_gif().

#define PX (  )     ( cx + (int)( ((float)rad)*sin(pscl*(double)(x)) ) )

Definition at line 48 of file gdcpie.cpp.

#define PY (  )     ( cy - (int)( ((float)rad)*cos(pscl*(double)(x)) ) )

Definition at line 49 of file gdcpie.cpp.

#define RAD_DIST1 (  )     ( (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) )

Definition at line 86 of file gdcpie.cpp.

Referenced by ocmpr(), and pie_gif().

#define RAD_DIST2 (  )     ( (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) )

Definition at line 87 of file gdcpie.cpp.

Referenced by ocmpr(), and pie_gif().

#define SET_RECT ( gdp,
x1,
x2,
y1,
y2   ) 

Value:

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

Definition at line 43 of file gdcpie.cpp.

#define TO_INT_DEG (  )     (int)rint( (double)((o)/(2.0*M_PI)*360.0) )

Definition at line 70 of file gdcpie.cpp.

Referenced by pie_gif().

#define TO_INT_DEG_CEIL (  )     (int)ceil( (double)((o)/(2.0*M_PI)*360.0) )

Definition at line 72 of file gdcpie.cpp.

Referenced by pie_gif().

#define TO_INT_DEG_FLOOR (  )     (int)floor( (double)((o)/(2.0*M_PI)*360.0) )

Definition at line 71 of file gdcpie.cpp.

Referenced by pie_gif().

#define TO_RAD (  )     ( (o)/360.0*(2.0*M_PI) )

Definition at line 73 of file gdcpie.cpp.

Referenced by pie_gif().


Function Documentation

void hola (  ) 

Definition at line 653 of file gdcpie.cpp.

00653             {
00654 fprintf(stderr,"hola");
00655 }

static int ocmpr ( const void *  a1,
const void *  b1 
) [static]

Definition at line 96 of file gdcpie.cpp.

References tmp_slice_t::angle, pie_3D_rad, RAD_DIST1, RAD_DIST2, and tmp_slice_t::slice.

Referenced by pie_gif().

00097 {
00098          struct tmp_slice_t *a = (tmp_slice_t *)a1;
00099          struct tmp_slice_t *b = (tmp_slice_t *)b1;
00100         if( RAD_DIST1(a->angle) < RAD_DIST2(b->angle) )
00101                 return 1;
00102         if( RAD_DIST1(a->angle) > RAD_DIST2(b->angle) )
00103                 return -1;
00104 
00105         /* a tie (will happen between each slice) */
00106         /* are we within pie_3D_rad */
00107         if( (a->angle < pie_3D_rad) && (pie_3D_rad < a->slice) ||
00108                 (a->slice < pie_3D_rad) && (pie_3D_rad < a->angle) )
00109                 return 1;
00110         if( (b->slice < pie_3D_rad) && (pie_3D_rad < b->angle) ||
00111                 (b->angle < pie_3D_rad) && (pie_3D_rad < b->slice) )
00112                 return -1;
00113 
00114         /* let slice angle decide */
00115         if( RAD_DIST1(a->slice) < RAD_DIST2(b->slice) )
00116                 return 1;
00117         if( RAD_DIST1(a->slice) > RAD_DIST2(b->slice) )
00118                 return -1;
00119 
00120         return 0;
00121 }

void pie_gif ( short  GIFWIDTH,
short  GIFHEIGHT,
FILE *  gif_fptr,
GDCPIE_TYPE  type,
int  num_points,
char **  lbl,
float *  val 
)

Definition at line 132 of file gdcpie.cpp.

References ABS, tmp_slice_t::angle, cnt_nl(), CX, CY, FALSE, GDC_3DPIE, GDC_fontc, GDC_NOCOLOR, GDCImageStringNL(), GDCPIE_PCT_ABOVE, GDCPIE_PCT_BELOW, GDCPIE_PCT_LEFT, GDCPIE_PCT_NONE, GDCPIE_PCT_RIGHT, gdImageArc(), gdImageCreate(), gdImageDestroy(), gdImageFilledPolygon(), gdImageFillToBorder(), gdImageGif(), gdImageLine(), gdImageString(), tmp_slice_t::hidden, tmp_slice_t::i, IX, IY, load_font_conversions(), MAX, MIN, MOD_2PI, ocmpr(), OX, OY, pie_3D_rad, RAD_DIST1, RAD_DIST2, tmp_slice_t::slice, TO_INT_DEG, TO_INT_DEG_CEIL, TO_INT_DEG_FLOOR, TO_RAD, and TRUE.

Referenced by main().

00139 {
00140 #ifndef WIN32
00141         int                     i;
00142 
00143         gdImagePtr      im;
00144         int                     BGColor,
00145                                 LineColor,
00146                                 PlotColor,
00147                                 EdgeColor,
00148                                 EdgeColorShd,
00149                                 SliceColor[num_points],
00150                                 SliceColorShd[num_points];
00151 
00152         float           rad = 0.0;                                      // radius
00153         float           tot_val = 0.0;
00154         float           pscl;
00155         int                     cx,                                                     // affects PX()
00156                                 cy;                                                     // affects PY()
00157                                                                 /* ~ 1% for a size of 100 pixs */
00158                                                                 /* label sizes will more dictate thos */
00159         float           min_grphable = ( GDCPIE_other_threshold < 0?
00160                                                                   100.0/(float)MIN(GIFWIDTH,GIFHEIGHT):
00161                                                                   (float)GDCPIE_other_threshold )/100.0;
00162         short           num_slices1 = 0,
00163                                 num_slices2 = 0;
00164         char            any_too_small = FALSE;
00165         char            others[num_points];
00166         float           slice_angle[3][num_points];     // must be used with others[]
00167         char            threeD = ( type == GDC_3DPIE );
00168 
00169         int                     xdepth_3D      = 0,                     // affects PX()
00170                                 ydepth_3D      = 0;                     // affects PY()
00171         int                     do3Dx = 0,                                      // reserved for macro use
00172                                 do3Dy = 0;
00173 
00174 //      GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360);
00175         pie_3D_rad = TO_RAD( GDCPIE_3d_angle );
00176 
00177         xdepth_3D      = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
00178         ydepth_3D      = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
00179 //      xdepth_3D      = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0;
00180 //      ydepth_3D      = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0;
00181 
00182         load_font_conversions();
00183 
00184         /* ----- get total value ----- */
00185         for( i=0; i<num_points; ++i )
00186                 tot_val += val[i];
00187 
00188         /* ----- pie sizing ----- */
00189         /* ----- make width room for labels, depth, etc.: ----- */
00190         /* ----- determine pie's radius ----- */
00191         {
00192         int             title_hgt  = GDCPIE_title? 1                    /*  title? horizontal text line */
00193                                                                            + GDC_fontc[GDCPIE_title_size].h
00194                                                                                 * (int)cnt_nl( GDCPIE_title, (int*)NULL )
00195                                                                            + 2:
00196                                                                            0;
00197         float   last = 0.0;
00198         float   label_explode_limit = 0.0;
00199         int             cheight,
00200                         cwidth;
00201 
00202         // maximum: no labels, explosions
00203         // gotta start somewhere
00204         rad = (float)MIN( GIFWIDTH/2-(1+ABS(xdepth_3D)), GIFHEIGHT/2-(1+ABS(ydepth_3D))-title_hgt );
00205 
00206         /* ok fix center, i.e., no floating re labels, explosion, etc. */
00207         cx = GIFWIDTH/2 /* - xdepth_3D */ ;
00208         cy = (GIFHEIGHT-title_hgt)/2 + title_hgt /* + ydepth_3D */ ;
00209 
00210         cheight = (GIFHEIGHT- title_hgt)/2 /* - ydepth_3D */ ;
00211         cwidth  = cx;
00212 
00213         /* walk around pie. determine spacing to edge */
00214         for( i=0; i<num_points; ++i )
00215                 {
00216                 float   thos_pct = val[i]/tot_val;                                              /* should never be > 100% */
00217                 float   thos = thos_pct*(2.0*M_PI);                                             /* pie-portion */
00218                 if( (thos_pct > min_grphable) ||                                                /* too small */
00219                         (!GDCPIE_missing || !GDCPIE_missing[i]) )                       /* still want angles */
00220                         {
00221                         int thos_explode = GDCPIE_explode? GDCPIE_explode[i]: 0;
00222                         double  thos_sin;
00223                         double  thos_cos;
00224                         slice_angle[0][i] = thos/2.0+last;                              /* mid-point on full pie */
00225                         slice_angle[1][i] = last;                                               /* 1st on full pie */
00226                         slice_angle[2][i] = thos+last;                                  /* 2nd on full pie */
00227                         thos_sin        = sin( (double)slice_angle[0][i] );
00228                         thos_cos        = cos( (double)slice_angle[0][i] );
00229 
00230                         if( !GDCPIE_missing || !(GDCPIE_missing[i]) )
00231                                 {
00232                                 short   lbl_wdth,
00233                                                 lbl_hgt;
00234                                 float   thos_y_explode_limit,
00235                                                 thos_x_explode_limit;
00236 
00237                                 /* start slice label height, width     */
00238                                 /*  accounting for PCT placement, font */
00239                                 if( lbl && lbl[i] )
00240                                         {
00241                                         char    foo[1+4+1+1];                                   /* XPG2 compatibility */
00242                                         int             pct_len;
00243                                         int             lbl_len = 0;
00244                                         lbl_hgt = ( cnt_nl(lbl[i], &lbl_len) + (GDCPIE_percent_labels == GDCPIE_PCT_ABOVE ||
00245                                                                                                                         GDCPIE_percent_labels == GDCPIE_PCT_BELOW? 1: 0) )
00246                                                           * (GDC_fontc[GDCPIE_label_size].h+1);
00247                                         sprintf( foo,
00248                                                          (GDCPIE_percent_labels==GDCPIE_PCT_LEFT ||
00249                                                           GDCPIE_percent_labels==GDCPIE_PCT_RIGHT) &&
00250                                                          lbl[i]? "(%.0f%%)":
00251                                                                          "%.0f%%",
00252                                                         thos_pct * 100.0 );
00253                                         pct_len = GDCPIE_percent_labels == GDCPIE_PCT_NONE? 0: strlen(foo);
00254                                         lbl_wdth = ( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT ||
00255                                                                  GDCPIE_percent_labels == GDCPIE_PCT_LEFT? lbl_len+1+pct_len:
00256                                                                                                                                                    MAX(lbl_len,pct_len) )
00257                                                            * GDC_fontc[GDCPIE_label_size].w;
00258                                         }
00259                                 else
00260                                         lbl_wdth = lbl_hgt = 0;
00261                                 /* end label height, width */
00262                                 
00263                                 /* diamiter limited by thos piont's: explosion, label                 */
00264                                 /* (radius to box @ slice_angle) - (explode) - (projected label size) */
00265                                 /* radius constraint due to labels */
00266                                 thos_y_explode_limit = (float)thos_cos==0.0? MAXFLOAT:
00267                                                                                 (       (float)( (double)cheight/ABS(thos_cos) ) - 
00268                                                                                         (float)( thos_explode + (lbl[i]? GDCPIE_label_dist: 0) ) -
00269                                                                                         (float)( lbl_hgt/2 ) / (float)ABS(thos_cos)     );
00270                                 thos_x_explode_limit = (float)thos_sin==0.0? MAXFLOAT:
00271                                                                                 (       (float)( (double)cwidth/ABS(thos_sin) ) - 
00272                                                                                         (float)( thos_explode + (lbl[i]? GDCPIE_label_dist: 0) ) -
00273                                                                                         (float)( lbl_wdth ) / (float)ABS(thos_sin)      );
00274 
00275                                 rad = MIN( rad, thos_y_explode_limit );
00276                                 rad = MIN( rad, thos_x_explode_limit );
00277 
00278                                 // ok at thos radius (which is most likely larger than final)
00279                                 // adjust for inter-label spacing
00280 //                              if( lbl[i] && *lbl[i] )
00281 //                                      {
00282 //                                      char which_edge = slice_angle[0][i] > M_PI? +1: -1;             // which semi
00283 //                                      last_label_yedge = cheight - (int)( (rad +                              // top or bottom of label
00284 //                                                                                                              (float)(thos_explode +
00285 //                                                                                                              (float)GDCPIE_label_dist)) * (float)thos_cos ) +
00286 //                                                                                           ( (GDC_fontc[GDCPIE_label_size].h+1)/2 +
00287 //                                                                                                      GDC_label_spacing )*which_edge;
00288 //                                      }
00289 
00290                                 /* radius constriant due to exploded depth */
00291                                 /* at each edge of the slice, and the middle */
00292                                 /* thos is really stupid */
00293                                 /*  thos section uses a different algorithm then above, but does the same thing */
00294                                 /*  could be combined, but each is ugly enough! */
00295 // PROTECT /0
00296                                 if( threeD )
00297                                         {
00298                                         short   j;
00299                                         int             thos_y_explode_pos;
00300                                         int             thos_x_explode_pos;
00301 
00302                                         // first N E S W (actually no need for N)
00303                                         if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) &&                               // E
00304                                                 (thos_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth )
00305                                                 rad -= (float)ABS( (double)(1+thos_x_explode_pos-(cx+cwidth))/sin(M_PI_2) );
00306                                         if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) &&               // W
00307                                                 (thos_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth )
00308                                                 rad -= (float)ABS( (double)(thos_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) );
00309                                         if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) &&                                   // S
00310                                                 (thos_y_explode_pos=OY(i,M_PI,1)) > cy+cheight )
00311                                                 rad -= (float)ABS( (double)(1+thos_y_explode_pos-(cy+cheight))/cos(M_PI) );
00312 
00313                                         for( j=0; j<3; ++j )
00314                                                 {
00315                                                 thos_y_explode_pos = IY(i,j,1);
00316                                                 if( thos_y_explode_pos < cy-cheight )
00317                                                         rad -= (float)ABS( (double)((cy-cheight)-thos_y_explode_pos)/cos((double)slice_angle[j][i]) );
00318                                                 if( thos_y_explode_pos > cy+cheight )
00319                                                         rad -= (float)ABS( (double)(1+thos_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) );
00320 
00321                                                 thos_x_explode_pos = IX(i,j,1);
00322                                                 if( thos_x_explode_pos < cx-cwidth )
00323                                                         rad -= (float)ABS( (double)((cx-cwidth)-thos_x_explode_pos)/sin((double)slice_angle[j][i]) );
00324                                                 if( thos_x_explode_pos > cx+cwidth )
00325                                                         rad -= (float)ABS( (double)(1+thos_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) );
00326                                                 }
00327                                         }
00328                                 }
00329                         others[i] = FALSE;
00330                         }
00331                 else
00332                         {
00333                         others[i] = TRUE;
00334                         slice_angle[0][i] = -MAXFLOAT;
00335                         }
00336                 last += thos;
00337                 }
00338         }
00339 
00340         /* ----- go ahead and start the GIF ----- */
00341         im = gdImageCreate( GIFWIDTH, GIFHEIGHT );
00342 
00343         /* --- allocate the requested colors --- */
00344         BGColor   = clrallocate( im, GDCPIE_BGColor );
00345         LineColor = clrallocate( im, GDCPIE_LineColor );
00346         PlotColor = clrallocate( im, GDCPIE_PlotColor );
00347         if( GDCPIE_EdgeColor != GDC_NOCOLOR )
00348          {
00349          EdgeColor = clrallocate( im, GDCPIE_EdgeColor );
00350          if( threeD )
00351           EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor );
00352          }
00353 
00354         /* --- set color for each slice --- */
00355         for( i=0; i<num_points; ++i )
00356                 if( GDCPIE_Color )
00357                         {
00358                         unsigned long   slc_clr = GDCPIE_Color[i];
00359 
00360                         SliceColor[i]     = clrallocate( im, slc_clr );
00361                         if( threeD )
00362                          SliceColorShd[i] = clrshdallocate( im, slc_clr );
00363                         }
00364                 else
00365                         {
00366                         SliceColor[i]     = PlotColor;
00367                         if( threeD )
00368                          SliceColorShd[i] = clrshdallocate( im, GDCPIE_PlotColor );
00369                         }
00370 
00371         pscl = (2.0*M_PI)/tot_val;
00372         
00373         /* ----- calc: smallest a slice can be ----- */
00374         /* 1/2 circum / num slices per side. */
00375         /*              determined by number of labels that'll fit (height) */
00376         /* scale to user values */
00377         /* ( M_PI / (GIFHEIGHT / (SFONTHGT+1)) ) */
00378 //      min_grphable = tot_val /
00379 //                                 ( 2.0 * (float)GIFHEIGHT / (float)(SFONTHGT+1+TFONTHGT+2) );
00380 
00381 
00382         if( threeD )
00383                 {
00384                 /* draw background shaded pie */
00385                 {
00386                 float   rad1 = rad;
00387                 for( i=0; i<num_points; ++i )
00388                         if( !(others[i]) &&
00389                                 (!GDCPIE_missing || !GDCPIE_missing[i]) )
00390                                 {
00391                                 float   rad = rad1;
00392 
00393                                 gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), SliceColorShd[i] );
00394                                 gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), SliceColorShd[i] );
00395 
00396                                 gdImageArc( im, CX(i,1), CY(i,1),
00397                                                                 rad*2, rad*2,
00398                                                                 TO_INT_DEG_FLOOR(slice_angle[1][i])+270,
00399                                                                 TO_INT_DEG_CEIL(slice_angle[2][i])+270,
00400                                                                 SliceColorShd[i] );
00401                                 rad1 = rad;
00402                                 rad *= 3.0/4.0;
00403                                 gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), SliceColorShd[i], SliceColorShd[i] );
00404                                 rad = rad1;
00405                                 if( GDCPIE_EdgeColor != GDC_NOCOLOR )
00406                                         {
00407                                         gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), EdgeColorShd );
00408                                         gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), EdgeColorShd );
00409                                         gdImageArc( im, CX(i,1), CY(i,1), 
00410                                                                         rad*2, rad*2,
00411                                                                         TO_INT_DEG(slice_angle[1][i])+270, TO_INT_DEG(slice_angle[2][i])+270,
00412                                                                         EdgeColorShd);
00413                                         }
00414                                 }
00415                 }
00416                 /* fill in connection to foreground pie */
00417                 /* thos is where we earn our keep */
00418                 {
00419                 struct tmp_slice_t      tmp_slice[2*num_points+2];
00420                 int                                     t,
00421                                                         num_slice_angles = 0;
00422 
00423                 for( i=0; i<num_points; ++i )
00424                         if( !GDCPIE_missing || !GDCPIE_missing[i] )
00425                                 {
00426                                 if( RAD_DIST1(slice_angle[1][i]) < RAD_DIST2(slice_angle[0][i]) )
00427                                         tmp_slice[num_slice_angles].hidden = FALSE;
00428                                 else
00429                                         tmp_slice[num_slice_angles].hidden = TRUE;
00430                                 tmp_slice[num_slice_angles].i       = i;
00431                                 tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
00432                                 tmp_slice[num_slice_angles++].angle = slice_angle[1][i];
00433                                 if( RAD_DIST1(slice_angle[2][i]) < RAD_DIST2(slice_angle[0][i]) )
00434                                         tmp_slice[num_slice_angles].hidden = FALSE;
00435                                 else
00436                                         tmp_slice[num_slice_angles].hidden = TRUE;
00437                                 tmp_slice[num_slice_angles].i       = i;
00438                                 tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
00439                                 tmp_slice[num_slice_angles++].angle = slice_angle[2][i];
00440                                 // identify which 2 slices (i) have a tangent parallel to depth angle 
00441                                 if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+M_PI_2) )
00442                                         {
00443                                         tmp_slice[num_slice_angles].i       = i;
00444                                         tmp_slice[num_slice_angles].hidden  = FALSE;
00445                                         tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
00446                                         tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 );
00447                                         }
00448                                 if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+3.0*M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+3.0*M_PI_2) )
00449                                         {
00450                                         tmp_slice[num_slice_angles].i       = i;
00451                                         tmp_slice[num_slice_angles].hidden  = FALSE;
00452                                         tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
00453                                         tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 );
00454                                         }
00455                                 }
00456 
00457                 qsort( (void *)tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr );
00458                 for( t=0; t<num_slice_angles; ++t )
00459                         {
00460                         gdPoint gdp[4];
00461 
00462                         i = tmp_slice[t].i;
00463 
00464                         gdp[0].x  = CX(i,0);                                    gdp[0].y = CY(i,0);
00465                         gdp[1].x  = CX(i,1);                                    gdp[1].y = CY(i,1);
00466                         gdp[2].x  = OX(i,tmp_slice[t].angle,1); gdp[2].y = OY(i,tmp_slice[t].angle,1);
00467                         gdp[3].x  = OX(i,tmp_slice[t].angle,0); gdp[3].y = OY(i,tmp_slice[t].angle,0);
00468 
00469                         if( !(tmp_slice[t].hidden) )
00470                                 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
00471                         else
00472                                 {
00473                                 rad -= 2.0;                                                                             /* no peeking */
00474                                 gdp[0].x  = OX(i,slice_angle[0][i],0);  gdp[0].y = OY(i,slice_angle[0][i],0);
00475                                 gdp[1].x  = OX(i,slice_angle[0][i],1);  gdp[1].y = OY(i,slice_angle[0][i],1);
00476                                 rad += 2.0;
00477                                 gdp[2].x  = OX(i,slice_angle[1][i],1);  gdp[2].y = OY(i,slice_angle[1][i],1);
00478                                 gdp[3].x  = OX(i,slice_angle[1][i],0);  gdp[3].y = OY(i,slice_angle[1][i],0);
00479                                 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
00480                                 gdp[2].x  = OX(i,slice_angle[2][i],1);  gdp[2].y = OY(i,slice_angle[2][i],1);
00481                                 gdp[3].x  = OX(i,slice_angle[2][i],0);  gdp[3].y = OY(i,slice_angle[2][i],0);
00482                                 gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
00483                                 }
00484                                 
00485 
00486                         if( GDCPIE_EdgeColor != GDC_NOCOLOR )
00487                                 {
00488                                 gdImageLine( im, CX(i,0), CY(i,0), CX(i,1), CY(i,1), EdgeColorShd );
00489                                 gdImageLine( im, OX(i,tmp_slice[t].angle,0), OY(i,tmp_slice[t].angle,0),
00490                                                                  OX(i,tmp_slice[t].angle,1), OY(i,tmp_slice[t].angle,1),
00491                                                          EdgeColorShd );
00492                                 }
00493                         }
00494                 }
00495                 }
00496 
00497 
00498         /* ----- pie face ----- */
00499         {
00500         // float        last = 0.0;
00501         float   rad1 = rad;
00502         for( i=0; i<num_points; ++i )
00503                 if( !others[i] &&
00504                         (!GDCPIE_missing || !GDCPIE_missing[i]) )
00505                         {
00506                         float   rad = rad1;
00507 
00508                         // last += val[i];
00509                         // EXPLODE_CX_CY( slice_angle[0][i], i );
00510                         gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), SliceColor[i] );
00511                         gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), SliceColor[i] );
00512 
00513                         gdImageArc( im, CX(i,0), CY(i,0), 
00514                                                         (int)rad*2, (int)rad*2,
00515                                                         TO_INT_DEG_FLOOR(slice_angle[1][i])+270,
00516                                                         TO_INT_DEG_CEIL(slice_angle[2][i])+270,
00517                                                         SliceColor[i] );
00518                         rad1 = rad;
00519                         rad *= 3.0/4.0;
00520                         gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), SliceColor[i], SliceColor[i] );
00521                         /* catch missed pixels on narrow slices */
00522                         gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] );
00523                         rad = rad1;
00524                         if( GDCPIE_EdgeColor != GDC_NOCOLOR )
00525                                 {
00526                                 gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), EdgeColor );
00527                                 gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), EdgeColor );
00528 
00529                                 gdImageArc( im, CX(i,0), CY(i,0), 
00530                                                                 rad*2, rad*2,
00531                                                                 TO_INT_DEG(slice_angle[1][i])+270, TO_INT_DEG(slice_angle[2][i])+270,
00532                                                                 EdgeColor );
00533                                 }
00534                         }
00535         }
00536 
00537         if( GDCPIE_title )
00538                 {
00539                 int     title_len;
00540 
00541                 cnt_nl( GDCPIE_title, &title_len );
00542                 GDCImageStringNL( im,
00543                                                   &GDC_fontc[GDCPIE_title_size],
00544                                                   (GIFWIDTH-title_len*GDC_fontc[GDCPIE_title_size].w)/2,
00545                                                   1,
00546                                                   GDCPIE_title,
00547                                                   LineColor,
00548                                                   GDC_JUSTIFY_CENTER );
00549                 }
00550 
00551         /* labels */
00552         if( lbl )
00553                 {
00554                 float   liner = rad;
00555 
00556                 rad += GDCPIE_label_dist;
00557                 for( i=0; i<num_points; ++i )
00558                         {
00559                         if( !others[i] &&
00560                                 (!GDCPIE_missing || !GDCPIE_missing[i]) )
00561                                 {
00562                                 char    pct_str[1+4+1+1];
00563                                 int             pct_wdth;
00564                                 int             lbl_wdth;
00565                                 short   num_nl = cnt_nl( lbl[i], &lbl_wdth );
00566                                 int             lblx,  pctx,
00567                                                 lbly,  pcty,
00568                                                 linex, liney;
00569 
00570                                 lbl_wdth *= GDC_fontc[GDCPIE_label_size].w;
00571                                 sprintf( pct_str,
00572                                                  (GDCPIE_percent_labels==GDCPIE_PCT_LEFT ||
00573                                                   GDCPIE_percent_labels==GDCPIE_PCT_RIGHT) &&
00574                                                  lbl[i]? "(%.0f%%)":
00575                                                                  "%.0f%%",
00576                                                 (val[i]/tot_val) * 100.0 );
00577                                 pct_wdth = GDCPIE_percent_labels == GDCPIE_PCT_NONE?
00578                                                         0:
00579                                                         strlen(pct_str) * GDC_fontc[GDCPIE_label_size].w;
00580 
00581                                 lbly = (liney = IY(i,0,0))-( num_nl * (1+GDC_fontc[GDCPIE_label_size].h) ) / 2;
00582                                 lblx = pctx = linex = IX(i,0,0);
00583 
00584                                 if( slice_angle[0][i] > M_PI )                                                          /* which semicircle */
00585                                         {
00586                                         lblx -= lbl_wdth;
00587                                         pctx = lblx;
00588                                         ++linex;
00589                                         }
00590                                 else
00591                                         --linex;
00592 
00593                                 switch( GDCPIE_percent_labels )
00594                                         {
00595                                         case GDCPIE_PCT_LEFT:   if( slice_angle[0][i] > M_PI )
00596                                                                                                 pctx -= lbl_wdth-1;
00597                                                                                         else
00598                                                                                                 lblx += pct_wdth+1;
00599                                                                                         pcty = IY(i,0,0) - ( 1+GDC_fontc[GDCPIE_label_size].h ) / 2;
00600                                                                                         break;
00601                                         case GDCPIE_PCT_RIGHT:  if( slice_angle[0][i] > M_PI )
00602                                                                                                 lblx -= pct_wdth-1;
00603                                                                                         else
00604                                                                                                 pctx += lbl_wdth+1;
00605                                                                                         pcty = IY(i,0,0) - ( 1+GDC_fontc[GDCPIE_label_size].h ) / 2;
00606                                                                                         break;
00607                                         case GDCPIE_PCT_ABOVE:  lbly += (1+GDC_fontc[GDCPIE_label_size].h) / 2;
00608                                                                                         pcty = lbly - (GDC_fontc[GDCPIE_label_size].h);
00609                                                                                         break;
00610                                         case GDCPIE_PCT_BELOW:  lbly -= (1+GDC_fontc[GDCPIE_label_size].h) / 2;
00611                                                                                         pcty = lbly + (GDC_fontc[GDCPIE_label_size].h) * num_nl;
00612                                                                                         break;
00613                                         case GDCPIE_PCT_NONE:
00614                                         default:
00615                                         break;
00616                                         }
00617 
00618                                 if( GDCPIE_percent_labels != GDCPIE_PCT_NONE )
00619                                         gdImageString( im,
00620                                                                    GDC_fontc[GDCPIE_label_size].f,
00621                                                                    slice_angle[0][i] <= M_PI? pctx:
00622                                                                                                                           pctx+lbl_wdth-pct_wdth,
00623                                                                    pcty,
00624                                                                    (unsigned char *)pct_str,
00625                                                                    LineColor );
00626                                 if( lbl[i] )
00627                                         GDCImageStringNL( im,
00628                                                                           &GDC_fontc[GDCPIE_label_size],
00629                                                                           lblx,
00630                                                                           lbly,
00631                                                                           lbl[i],
00632                                                                           LineColor,
00633                                                                           slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT:
00634                                                                                                                                  GDC_JUSTIFY_RIGHT );
00635                                 if( GDCPIE_label_line )
00636                                         {
00637                                         float   rad = liner;
00638                                         gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor );
00639                                         }
00640                                 }
00641                         }
00642                 rad -= GDCPIE_label_dist;
00643                 }
00644 
00645         gdImageGif(im, gif_fptr);
00646 
00647         gdImageDestroy(im);
00648         return;
00649 #endif
00650 }


Variable Documentation

float dist_foo1 [static]

Definition at line 88 of file gdcpie.cpp.

float dist_foo2 [static]

Definition at line 88 of file gdcpie.cpp.

struct GDC_FONT_T GDC_fontc[]

Definition at line 11 of file gdc.cpp.

Referenced by load_font_conversions(), out_err(), out_graph(), and pie_gif().

float pie_3D_rad [static]

Definition at line 82 of file gdcpie.cpp.

Referenced by ocmpr(), and pie_gif().


Generated on Sat Dec 15 00:01:28 2007 for BulmaGes by  doxygen 1.5.1