annotate tools/x11coord.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
rev   line source
tomwalters@0 1 /****************************************************************************
tomwalters@0 2 * Routines for x11coord package.
tomwalters@0 3 ****************************************************************************/
tomwalters@0 4
tomwalters@0 5 #include <stdio.h>
tomwalters@0 6 #include <math.h>
tomwalters@0 7 #include "x11coord.h"
tomwalters@0 8
tomwalters@0 9 /****************************************************************************
tomwalters@0 10 * Set parameters for data-pixel conversion macros
tomwalters@0 11 ****************************************************************************/
tomwalters@0 12 /* Initialize parameters for size and position of window on screen */
tomwalters@0 13 set_window_parameters(xorg,yorg, width,height)
tomwalters@0 14 int xorg,yorg; /* Pixel coords of window origin wrt theDisplay origin */
tomwalters@0 15 int width,height; /* Size of window (in pixels) */
tomwalters@0 16 {
tomwalters@0 17 _xorg = xorg;
tomwalters@0 18 _yorg = yorg;
tomwalters@0 19 _width = width;
tomwalters@0 20 _height = height;
tomwalters@0 21 set_bordered_box((int)0); /* defaults */
tomwalters@0 22 set_data_parameters((int)0,(int)0, (float)0,(float)0, (float)width,(float)height);
tomwalters@0 23 }
tomwalters@0 24
tomwalters@0 25 /* Initialize parameters for size and position of box in preset window */
tomwalters@0 26 set_box_parameters(xorg,yorg, width,height)
tomwalters@0 27 int xorg,yorg; /* Pixel coords of box origin wrt bottom-left of window */
tomwalters@0 28 int width,height; /* Size of window (in pixels) */
tomwalters@0 29 {
tomwalters@0 30 _Xp0 = xorg;
tomwalters@0 31 _Yp0 = _height - yorg;
tomwalters@0 32 _Xp1 = xorg + width;
tomwalters@0 33 _Yp1 = _height - (yorg + height);
tomwalters@0 34 _Wb = _Xp1 - _Xp0;
tomwalters@0 35 _Hb = _Yp0 - _Yp1;
tomwalters@0 36 set_data_parameters((int)0,(int)0, (float)0,(float)0, (float)width,(float)height);
tomwalters@0 37 }
tomwalters@0 38
tomwalters@0 39
tomwalters@0 40 /* Initialize parameters for size and position of box in preset window, */
tomwalters@0 41 /* given the width of the border as a %age of the window size on any side */
tomwalters@0 42 set_bordered_box(bpc)
tomwalters@0 43 int bpc;
tomwalters@0 44 {
tomwalters@0 45 int xborder, yborder, Wb, Hb;
tomwalters@0 46
tomwalters@0 47 xborder = (_width * bpc) / 100;
tomwalters@0 48 yborder = (_height * bpc) / 100;
tomwalters@0 49 Wb = _width - 2*xborder;
tomwalters@0 50 Hb = _height - 2*yborder;
tomwalters@0 51 set_box_parameters(xborder,yborder, Wb,Hb);
tomwalters@0 52 }
tomwalters@0 53
tomwalters@0 54 /* Initialize parameters for area and location of data-space to appear in box */
tomwalters@0 55 set_data_parameters(xp0,yp0, xd0,yd0, xrange,yrange)
tomwalters@0 56 int xp0,yp0; /* Box origin shift as a percentage of box width,height */
tomwalters@0 57 float xd0,yd0; /* Data coord to appear under box origin. */
tomwalters@0 58 float xrange,yrange;/* Data ranges (corresponding to box width and height). */
tomwalters@0 59 {
tomwalters@0 60 _xrange = xrange;
tomwalters@0 61 _yrange = yrange;
tomwalters@0 62 _xshift = (_Wb * xp0)/100;
tomwalters@0 63 _yshift = (_Hb * yp0)/100;
tomwalters@0 64 _xd0 = xd0;
tomwalters@0 65 _yd0 = yd0;
tomwalters@0 66 _Xd0 = xd0 - _xrange*((float)_xshift/_Wb);
tomwalters@0 67 _Yd0 = yd0 - _yrange*((float)_yshift/_Hb);
tomwalters@0 68 _Xd1 = xd0 + (_xrange - _xrange*((float)_xshift/_Wb));
tomwalters@0 69 _Yd1 = yd0 + (_yrange - _yrange*((float)_yshift/_Hb));
tomwalters@0 70
tomwalters@0 71 _xoffset = _Xp0 + _xshift - _xd0*_Wb/_xrange ;
tomwalters@0 72 _yoffset = _Yp1 + _Hb - _yshift + _yd0*_Hb/_yrange ;
tomwalters@0 73 _xscale = _Wb/_xrange;
tomwalters@0 74 _yscale = _Hb/_yrange;
tomwalters@0 75 }
tomwalters@0 76
tomwalters@0 77
tomwalters@0 78 /****************************************************************************
tomwalters@0 79 * Creating windows, initializing GC and Font, etc.. (X11 specific)
tomwalters@0 80 ****************************************************************************/
tomwalters@0 81 xopen()
tomwalters@0 82 {
tomwalters@0 83
tomwalters@0 84 if ((char *)getenv("DISPLAY") == (char *)0 ) {
tomwalters@0 85 fprintf(stderr,"DISPLAY not set\n");
tomwalters@0 86 exit(1);
tomwalters@0 87 }
tomwalters@0 88 if ((theDisplay = XOpenDisplay(NULL)) == NULL) {
tomwalters@0 89 fprintf(stderr,"Can't open display %s\n", getenv("DISPLAY"));
tomwalters@0 90 exit(1);
tomwalters@0 91 }
tomwalters@0 92 theScreen = XDefaultScreen(theDisplay);
tomwalters@0 93 theForeground = theBlack = XBlackPixel(theDisplay,theScreen); /* Black lines, text, and borders */
tomwalters@0 94 theBackground = theWhite = XWhitePixel(theDisplay,theScreen); /* White background */
tomwalters@0 95 theWidth = XDisplayWidth(theDisplay,theScreen);
tomwalters@0 96 theHeight = XDisplayHeight(theDisplay,theScreen);
tomwalters@0 97 theGC = initGC() ;
tomwalters@0 98 }
tomwalters@0 99
tomwalters@0 100
tomwalters@0 101 /*
tomwalters@0 102 eg: xgc( 1, "times_roman14" ) ;
tomwalters@0 103 */
tomwalters@0 104
tomwalters@0 105 xgc( linewidth, fontstr )
tomwalters@0 106 int linewidth ;
tomwalters@0 107 char *fontstr ;
tomwalters@0 108 {
tomwalters@0 109 setLinewidth( linewidth ) ;
tomwalters@0 110 theFont = (XFontStruct *)0;
tomwalters@0 111 if ( setFont( fontstr ) == NULL ) {
tomwalters@0 112 fprintf( stderr,"can't load font %s\n", fontstr ) ;
tomwalters@0 113 exit( 1 ) ;
tomwalters@0 114 }
tomwalters@0 115 }
tomwalters@0 116
tomwalters@0 117
tomwalters@0 118 GC initGC()
tomwalters@0 119 {
tomwalters@0 120 GC gc;
tomwalters@0 121
tomwalters@0 122 gc = XDefaultGC(theDisplay, theScreen);
tomwalters@0 123 /* Set foreground and background pixel values (ie colours) */
tomwalters@0 124 XSetState(theDisplay, gc, theForeground, theBackground, GXcopy, AllPlanes);
tomwalters@0 125 return gc;
tomwalters@0 126 }
tomwalters@0 127
tomwalters@0 128
tomwalters@0 129
tomwalters@0 130 setLinewidth(width) /* Set line width, used by XDrawLine commands */
tomwalters@0 131 int width;
tomwalters@0 132 {
tomwalters@0 133 XGCValues gcvalues;
tomwalters@0 134
tomwalters@0 135 gcvalues.line_width = width;
tomwalters@0 136 XChangeGC(theDisplay, theGC, GCLineWidth, &gcvalues);
tomwalters@0 137 }
tomwalters@0 138
tomwalters@0 139
tomwalters@0 140 setFont(fontname) /* Free last theFont (unless null) and load new font */
tomwalters@0 141 char *fontname; /* return null if can't load font */
tomwalters@0 142 {
tomwalters@0 143 if (theFont != (XFontStruct *)0) XFreeFont(theDisplay,theFont);
tomwalters@0 144 if ((theFont = XLoadQueryFont(theDisplay, fontname)) == NULL)
tomwalters@0 145 return 0 ;
tomwalters@0 146 XSetFont(theDisplay, theGC, theFont->fid);
tomwalters@0 147 return 1 ;
tomwalters@0 148 }
tomwalters@0 149
tomwalters@0 150
tomwalters@0 151 Window xCreate(name, event_mask, xorg,yorg, width,height)
tomwalters@0 152 char *name;
tomwalters@0 153 long event_mask;
tomwalters@0 154 int xorg,yorg, width,height;
tomwalters@0 155 {
tomwalters@0 156 Window w;
tomwalters@0 157
tomwalters@0 158 if ((w = XCreateSimpleWindow(theDisplay, XDefaultRootWindow(theDisplay),
tomwalters@0 159 xorg, yorg, (unsigned)width, (unsigned)height, 1,
tomwalters@0 160 theForeground, theBackground)) == (Window)0 ) {
tomwalters@0 161 fprintf(stderr,"can't create window\n");
tomwalters@0 162 exit(1);
tomwalters@0 163 }
tomwalters@0 164 XStoreName(theDisplay, w, name);
tomwalters@0 165 XSelectInput(theDisplay, w, event_mask);
tomwalters@0 166 XMapWindow(theDisplay, w);
tomwalters@0 167 XFlush(theDisplay);
tomwalters@0 168 return w;
tomwalters@0 169 }
tomwalters@0 170
tomwalters@0 171
tomwalters@0 172 /****************************************************************************
tomwalters@0 173 * Drawing axes and boxes in a given window w.
tomwalters@0 174 ****************************************************************************/
tomwalters@0 175 axis(w, p0,p1, ploc,axis)
tomwalters@0 176 Window w;
tomwalters@0 177 int p0,p1; /* First and last axis pixel distances, relative to parent */
tomwalters@0 178 int ploc; /* Location of axis (orthogonal pixel dist from parent org) */
tomwalters@0 179 char axis; /* Orientation of axis ('x' or 'y') */
tomwalters@0 180 {
tomwalters@0 181 if (axis=='x') XDrawLine(theDisplay, w, theGC, p0,ploc, p1,ploc);
tomwalters@0 182 if (axis=='y') XDrawLine(theDisplay, w, theGC, ploc,p0, ploc,p1);
tomwalters@0 183 }
tomwalters@0 184
tomwalters@0 185 box(w, x0,y0, x1,y1) /* draw rectangular box */
tomwalters@0 186 Window w;
tomwalters@0 187 int x0,y0, x1,y1;
tomwalters@0 188 {
tomwalters@0 189 axis(w, y0,y1, x0,'y');
tomwalters@0 190 axis(w, y0,y1, x1,'y');
tomwalters@0 191 axis(w, x0,x1, y0,'x');
tomwalters@0 192 axis(w, x0,x1, y1,'x');
tomwalters@0 193 }
tomwalters@0 194
tomwalters@0 195 /****************************************************************************
tomwalters@0 196 * Calibrating axes and boxes in a given window w.
tomwalters@0 197 ****************************************************************************/
tomwalters@0 198 struct mark_struct {
tomwalters@0 199 int type; /* type= HALFMARK or FULLMARK */
tomwalters@0 200 int position; /* mark position on screen relative to the parent system */
tomwalters@0 201 char label[16]; /* ASCII label of real plot value (FULLMARK only) */
tomwalters@0 202 };
tomwalters@0 203
tomwalters@0 204 #define NMARKS 150 /* size of array of calibration marks */
tomwalters@0 205 #define FULLMARK 10 /* Box calibration marks */
tomwalters@0 206 #define HALFMARK 5
tomwalters@0 207
tomwalters@0 208 calibrate_Axis(w, p0,p1, d0,d1, ploc,axis)
tomwalters@0 209 Window w;
tomwalters@0 210 int p0,p1; /* First and last axis pixel distances, relative to parent */
tomwalters@0 211 float d0,d1; /* First and last axis data values */
tomwalters@0 212 int ploc; /* Location of axis (orthogonal pixel dist from parent org) */
tomwalters@0 213 char axis; /* Orientation of axis ('x' or 'y') */
tomwalters@0 214 {
tomwalters@0 215 int n;
tomwalters@0 216 struct mark_struct mark[NMARKS];
tomwalters@0 217
tomwalters@0 218 if ((n = calibrate(mark, p0,p1, d0,d1)) < 0) {
tomwalters@0 219 fprintf(stderr,"mark array out of space, increase NMARKS\n");
tomwalters@0 220 exit(1);
tomwalters@0 221 }
tomwalters@0 222 if (axis=='x') plotX(w, ploc, mark, n);
tomwalters@0 223 if (axis=='y') plotY(w, ploc, mark, n);
tomwalters@0 224 }
tomwalters@0 225
tomwalters@0 226
tomwalters@0 227 calibrate_Box(w, xp0,yp0, xp1,yp1, xd0,yd0, xd1,yd1)
tomwalters@0 228 Window w;
tomwalters@0 229 int xp0,yp0, xp1,yp1;
tomwalters@0 230 float xd0,yd0, xd1,yd1;
tomwalters@0 231 {
tomwalters@0 232 calibrate_Axis(w, xp0,xp1, xd0,xd1, yp0,'x');
tomwalters@0 233 calibrate_Axis(w, yp0,yp1, yd0,yd1, xp0,'y');
tomwalters@0 234 }
tomwalters@0 235
tomwalters@0 236
tomwalters@0 237 plotX(w, Y, mark, n) /* Plot calibration marks along an X axis */
tomwalters@0 238 Window w;
tomwalters@0 239 int Y;
tomwalters@0 240 struct mark_struct mark[];
tomwalters@0 241 int n;
tomwalters@0 242 {
tomwalters@0 243 int i, H, W;
tomwalters@0 244 int X;
tomwalters@0 245
tomwalters@0 246 for (i = 0 ; i < n ; i++) {
tomwalters@0 247 X = mark[i].position;
tomwalters@0 248 XDrawLine(theDisplay, w, theGC, X, Y, X, Y+mark[i].type);
tomwalters@0 249 if (mark[i].type == FULLMARK) /* Label calibration value */
tomwalters@0 250 {
tomwalters@0 251 W = stringwidth(mark[i].label) / 2; /* Shift label left by half width */
tomwalters@0 252 H=20; /* Shift label down a bit */
tomwalters@0 253 XDrawString(theDisplay, w, theGC, X-W, Y+H, mark[i].label, strlen(mark[i].label));
tomwalters@0 254 }
tomwalters@0 255 }
tomwalters@0 256 }
tomwalters@0 257
tomwalters@0 258 plotY(w, X, mark, n) /* Plot calibration marks along a Y axis */
tomwalters@0 259 Window w;
tomwalters@0 260 int X;
tomwalters@0 261 struct mark_struct mark[];
tomwalters@0 262 int n;
tomwalters@0 263 {
tomwalters@0 264 int i, H, W;
tomwalters@0 265 int Y;
tomwalters@0 266
tomwalters@0 267 for (i = 0 ; i < n ; i++) {
tomwalters@0 268 Y = mark[i].position;
tomwalters@0 269 XDrawLine(theDisplay, w, theGC, X, Y, X-mark[i].type, Y);
tomwalters@0 270 if (mark[i].type == FULLMARK) { /* Label calibration value */
tomwalters@0 271 W = stringwidth(mark[i].label) + 10;/* Shift label left by width */
tomwalters@0 272 H=5; /* Shift label down a bit */
tomwalters@0 273 XDrawString(theDisplay, w, theGC, X-W, Y+H, mark[i].label, strlen(mark[i].label));
tomwalters@0 274 }
tomwalters@0 275 }
tomwalters@0 276 }
tomwalters@0 277
tomwalters@0 278 /****************************************************************************
tomwalters@0 279 * Macros used by calibration routines
tomwalters@0 280 ****************************************************************************/
tomwalters@0 281 #define rem(x,y) fabs((x) - (y)*(int)((x)/(y))) /* real remainder */
tomwalters@0 282 #define rem2(x,y) fabs((x) - (y)*(int)((x)/(y)-0.5)) /* real remainder for -ve x */
tomwalters@0 283 #define round(x) ((x >= 0) ? ((int)(x+0.5)) : ((int)(x-0.5)))
tomwalters@0 284 #define min(x,y) ((x < y) ? x : y)
tomwalters@0 285 #define EPS 1.0e-5
tomwalters@0 286
tomwalters@0 287 /****************************************************************************
tomwalters@0 288 * Calibrate one axis.
tomwalters@0 289 * Fill the given array "mark" with mark structs, and return the number of
tomwalters@0 290 * marks, or -1 indicating that the mark array is full, (and NMARKS should
tomwalters@0 291 * be increased).
tomwalters@0 292 * Each mark struct in the array gives the mark position (in pixels relative
tomwalters@0 293 * to the given first and last mark positions), the mark type (being HALFMARK
tomwalters@0 294 * or FULLMARK), and a label string (for each FULLMARK only).
tomwalters@0 295 * Arguments are as follows:
tomwalters@0 296 * p0,p1 first and last screen positions in pixels, relative to the parent
tomwalters@0 297 * window, (used to calculate mark positions on the screen).
tomwalters@0 298 * d0,d1 first and last data values (used to calculate axis labels).
tomwalters@0 299 *****************************************************************************/
tomwalters@0 300 calibrate(mark, p0, p1, d0, d1)
tomwalters@0 301 struct mark_struct mark[];
tomwalters@0 302 int p0,p1; /* first and last axis pixel distances, relative to parent */
tomwalters@0 303 float d0,d1; /* first and last axis data values */
tomwalters@0 304 {
tomwalters@0 305 int position, plotsize, nmarks=0;
tomwalters@0 306 float div, hdiv, offset, hoffset, value, hvalue;
tomwalters@0 307 float range, scalefactor, maxerror, nextvalue, lastvalue;
tomwalters@0 308 float label, real_division (), sig_figs ();
tomwalters@0 309 float tmp;
tomwalters@0 310
tomwalters@0 311 if (d0 > d1) { /* swap to get +ve range */
tomwalters@0 312 tmp = d1; d1 = d0; d0 = tmp;
tomwalters@0 313 tmp = p1; p1 = p0; p0 = tmp;
tomwalters@0 314 }
tomwalters@0 315
tomwalters@0 316 plotsize = p1-p0; /* screen size */
tomwalters@0 317 range = d1-d0; /* real plot range */
tomwalters@0 318
tomwalters@0 319 div = real_division (range);
tomwalters@0 320 hdiv = div/10; /* Halfmarks every 10th labelled division (fullmark) */
tomwalters@0 321
tomwalters@0 322 /* calculate real offset and hoffset of 1st fullmark and halfmark */
tomwalters@0 323 /* respectively, from first (ie min) real value d0. */
tomwalters@0 324 if (d0 == 0)
tomwalters@0 325 {
tomwalters@0 326 offset = hoffset = 0;
tomwalters@0 327 }
tomwalters@0 328 else
tomwalters@0 329 {
tomwalters@0 330 if (d0 > 0)
tomwalters@0 331 {
tomwalters@0 332 offset = div - rem(d0,div);
tomwalters@0 333 hoffset = hdiv - rem(d0,hdiv);
tomwalters@0 334 }
tomwalters@0 335 else /* (d0 < 0) */
tomwalters@0 336 {
tomwalters@0 337 offset = rem2(d0,div);
tomwalters@0 338 hoffset = rem2(d0,hdiv);
tomwalters@0 339 }
tomwalters@0 340 }
tomwalters@0 341
tomwalters@0 342 value = d0 + offset; /* real value of 1st fullmark */
tomwalters@0 343 hvalue = d0 + hoffset; /* real value of 1st halfmark */
tomwalters@0 344
tomwalters@0 345 scalefactor = (float)plotsize/range; /* scale factor between real range and plotted range */
tomwalters@0 346 maxerror = hdiv/2;
tomwalters@0 347 lastvalue = d0+range+maxerror;
tomwalters@0 348 nextvalue = value-maxerror;
tomwalters@0 349
tomwalters@0 350 /* Plot halfmarks up to 1st fullmark */
tomwalters@0 351
tomwalters@0 352 for ( ; hvalue < nextvalue ; hvalue += hdiv)
tomwalters@0 353 {
tomwalters@0 354 position = (int)((hvalue-d0) * scalefactor); /* actual plotted position (in plot range) */
tomwalters@0 355 setmark (&mark[nmarks], HALFMARK, p0+position, NULL);
tomwalters@0 356 if (++nmarks >= NMARKS) return -1;
tomwalters@0 357 }
tomwalters@0 358
tomwalters@0 359 /* Loop plotting fullmarks, with halfmarks between each */
tomwalters@0 360
tomwalters@0 361 for ( ; value < lastvalue ; value += div)
tomwalters@0 362 {
tomwalters@0 363 position = (int)((value-d0) * scalefactor); /* actual plotted position */
tomwalters@0 364 label = sig_figs (value, range);
tomwalters@0 365 setmark (&mark[nmarks], FULLMARK, p0+position, label);
tomwalters@0 366 if (++nmarks >= NMARKS) return -1;
tomwalters@0 367
tomwalters@0 368 /* Loop plotting halfmarks between each fullmark */
tomwalters@0 369
tomwalters@0 370 nextvalue = value+div-maxerror;
tomwalters@0 371 if (nextvalue > lastvalue) nextvalue = lastvalue;
tomwalters@0 372 for (hvalue = value+hdiv ; hvalue < nextvalue ; hvalue += hdiv)
tomwalters@0 373 {
tomwalters@0 374 position = (int)((hvalue-d0) * scalefactor); /* actual plotted position */
tomwalters@0 375 setmark (&mark[nmarks], HALFMARK, p0+position, NULL);
tomwalters@0 376 if (++nmarks >= NMARKS) return -1;
tomwalters@0 377 }
tomwalters@0 378 }
tomwalters@0 379 return nmarks;
tomwalters@0 380 }
tomwalters@0 381
tomwalters@0 382
tomwalters@0 383 float
tomwalters@0 384 real_division (range) /* Return recomended division between fullmarks on real scale */
tomwalters@0 385 float range;
tomwalters@0 386 {
tomwalters@0 387 int power;
tomwalters@0 388 float scalefactor, scaled_range, div;
tomwalters@0 389
tomwalters@0 390 if (range <= 0) {
tomwalters@0 391 fprintf(stderr,"range must be positive\n");
tomwalters@0 392 exit(1);
tomwalters@0 393 }
tomwalters@0 394
tomwalters@0 395 if (range >= 1.0)
tomwalters@0 396 power = -(int)(log10(range) + EPS);
tomwalters@0 397 else
tomwalters@0 398 power = -(int)(log10(range) - 1 + EPS);
tomwalters@0 399 scalefactor = pow (10.0, (float)power);
tomwalters@0 400
tomwalters@0 401 scaled_range = range * scalefactor; /* scaled_range is (1 <= range <= 9.9999) */
tomwalters@0 402
tomwalters@0 403 /* Set division size (in scaled_range) between given breaks in the scale */
tomwalters@0 404
tomwalters@0 405 if (scaled_range < 1.5) div = 0.1;
tomwalters@0 406 else if (scaled_range < 2.5) div = 0.2;
tomwalters@0 407 else if (scaled_range < 5.0) div = 0.5;
tomwalters@0 408 else div = 1.0;
tomwalters@0 409
tomwalters@0 410 return (div/scalefactor); /* return div scaled down to real range */
tomwalters@0 411 }
tomwalters@0 412
tomwalters@0 413
tomwalters@0 414 float
tomwalters@0 415 sig_figs (value, range) /* Round value to 2 sig figs on the scale of the range */
tomwalters@0 416 float value, range;
tomwalters@0 417 {
tomwalters@0 418 int power;
tomwalters@0 419 float scalefactor, scaled_value;
tomwalters@0 420
tomwalters@0 421 if (range >= 1.0)
tomwalters@0 422 power = 1-(int)(log10(range) + EPS);
tomwalters@0 423 else
tomwalters@0 424 power = 1-(int)(log10(range) - 1 + EPS);
tomwalters@0 425 scalefactor = pow (10.0, (float)power);
tomwalters@0 426
tomwalters@0 427 scaled_value = value * scalefactor; /* scaled_value is in range (10 <= range <= 99.999) */
tomwalters@0 428 value = round(scaled_value);
tomwalters@0 429
tomwalters@0 430 return (value/scalefactor);
tomwalters@0 431 }
tomwalters@0 432
tomwalters@0 433 /* Fill one mark struct with the mark position, type, and label */
tomwalters@0 434 setmark (mark, mark_type, x, x1)
tomwalters@0 435 struct mark_struct *mark;
tomwalters@0 436 int mark_type;
tomwalters@0 437 int x; /* position */
tomwalters@0 438 float x1; /* value of label */
tomwalters@0 439 {
tomwalters@0 440 if ((mark->type = mark_type) == FULLMARK)
tomwalters@0 441 labelstring(mark->label, x1);
tomwalters@0 442 mark->position = x;
tomwalters@0 443 }
tomwalters@0 444
tomwalters@0 445 /* Return with str containing an appropriate ASCII string of the given value */
tomwalters@0 446 labelstring(str, value)
tomwalters@0 447 char *str;
tomwalters@0 448 float value;
tomwalters@0 449 {
tomwalters@0 450 float decval; /* decimal part of a number */
tomwalters@0 451
tomwalters@0 452 decval = value - (int)value;
tomwalters@0 453 if (value < 0) decval = -decval;
tomwalters@0 454 if (value > -EPS && value < EPS) sprintf(str,"0" );
tomwalters@0 455 else if (fabs(value) >= 10000) sprintf(str,"%g", value);
tomwalters@0 456 else if (decval <= EPS) sprintf(str,"%d", (int)value);
tomwalters@0 457 else if (decval <= 0.001) sprintf(str,"%.4f", value);
tomwalters@0 458 else if (decval <= 0.01) sprintf(str,"%.3f", value);
tomwalters@0 459 else if (decval <= 0.1) sprintf(str,"%.2f", value);
tomwalters@0 460 else sprintf(str,"%.1f", value);
tomwalters@0 461 }
tomwalters@0 462
tomwalters@0 463 /****************************************************************************
tomwalters@0 464 Text printing routines.
tomwalters@0 465 ****************************************************************************/
tomwalters@0 466 /* The origin for a char is an x-value of `lbearing' to the left of the */
tomwalters@0 467 /* left-most char ink, and a y-value between the `ascent' and the */
tomwalters@0 468 /* `descent', (ie along an underline), (ref 6-20). */
tomwalters@0 469 /* The `margin' is an ad-hoc idea. */
tomwalters@0 470
tomwalters@0 471 /* Return the width in pixels of the given string, using the current font */
tomwalters@0 472 stringwidth(str)
tomwalters@0 473 char *str;
tomwalters@0 474 {
tomwalters@0 475 int width;
tomwalters@0 476
tomwalters@0 477 width = XTextWidth(theFont, str, strlen(str));
tomwalters@0 478 return width;
tomwalters@0 479 }
tomwalters@0 480
tomwalters@0 481 /* Return the height in pixels of the given string, using the current font */
tomwalters@0 482 stringheight(str)
tomwalters@0 483 char *str;
tomwalters@0 484 {
tomwalters@0 485 XCharStruct stringinfo; /* ref Xlib 6-17 */
tomwalters@0 486 int dr, fa, fd;
tomwalters@0 487 short asc, desc, width;
tomwalters@0 488 int height;
tomwalters@0 489
tomwalters@0 490 XTextExtents(theFont, str, strlen(str), &dr,&fa,&fd, &stringinfo);
tomwalters@0 491 asc = stringinfo.ascent; /* max of char ascents in string */
tomwalters@0 492 desc = stringinfo.descent; /* max of char descents in string */
tomwalters@0 493 width = stringinfo.width; /* sum of char widths across string */
tomwalters@0 494 height = asc+desc; /* max height over all chars */
tomwalters@0 495 return height;
tomwalters@0 496 }
tomwalters@0 497
tomwalters@0 498
tomwalters@0 499 /****************************************************************************
tomwalters@0 500 Misc routines.
tomwalters@0 501 ****************************************************************************/
tomwalters@0 502 /* Plot a dot at data coord (x,y). Dotsize=0,1,2,3,.., and size 0 is empty */
tomwalters@0 503 Dot(w,x,y,dotsize)
tomwalters@0 504 Window w;
tomwalters@0 505 float x,y;
tomwalters@0 506 int dotsize;
tomwalters@0 507 {
tomwalters@0 508 int d, X,Y;
tomwalters@0 509
tomwalters@0 510 if ((d=dotsize-1) >= 0) {
tomwalters@0 511 if (d==0) /* dotsize = 1 */
tomwalters@0 512 Point(w, x,y);
tomwalters@0 513 else { /* dotsize > 1 */
tomwalters@0 514 for (X=(-d) ; X<=d ; X++)
tomwalters@0 515 for (Y=(-d) ; Y<=d ; Y++)
tomwalters@0 516 XDrawPoint(theDisplay,w,theGC,px(x)+X,py(y)+Y);
tomwalters@0 517 }
tomwalters@0 518 }
tomwalters@0 519 }