Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
rleClock.c
Go to the documentation of this file.
1 /*
2  * rleClock
3  * --------
4  *
5  * Generates a clock face with digital output above it, in Utah Raster toolkit
6  * format.
7  *
8  * SYNOPSIS
9  * rleClock [options]
10  *
11  * Writes an RLE file to stdout containins a clock face image according to
12  * the options.
13  *
14  * OPTIONS
15  *
16  * Too many to describe. Type "rleClock -help" for a listing.
17  *
18  * AUTHOR
19  * Bob Brown rlb@riacs.edu
20  * RIACS 415 694 5407
21  * Mail Stop 230-5
22  * NASA Ames Research Center
23  * Moffett Field
24  * CA 94035
25  *
26  * First draft, December 3, 1987
27  * lineDots() written by Nancy Blachman Jan, 1987
28  * font.src derived from NBS fonts.
29  */
30 static char rcsid[] = "$Header: /l/spencer/src/urt/tools/clock/RCS/rleClock.c,v 3.0.1.2 1992/04/30 14:19:38 spencer Exp $";
31 /*
32 rleClock() Tag the file.
33 */
34 
35 #include <stdio.h>
36 #include <math.h>
37 #include <ctype.h>
38 #include "rle.h"
39 #include <sys/types.h>
40 #include <time.h>
41 #include "font.h"
42 
43 /*
44  * Program parameters defaults
45  *
46  * Note: within the program, radius is on a scale of 0..1 and then converted in
47  * the polar coordinate conversion routines.
48  */
49 
50 #define XSIZE 128
51 #define YTEXTSIZE 0
52 #define YCLOCKSIZE XSIZE
53 #define TICKS 12
54 #define DOTS 1
55 #define FORMATSTRING "%02l:%02b"
56 #define FACE_EDGE_COLOR { 255, 255, 255 }
57 #define HAND_COLOR { 255, 255, 255 }
58 #define TEXT_COLOR { 255, 255, 255 }
59 #define LITTLEHANDSCALE 12
60 #define BIGHANDSCALE 60
61 
62 #define HANDWIDTH 0.075
63 
64 #ifndef TRUE
65 #define TRUE 1
66 #define FALSE 0
67 #endif
68 typedef char bool;
69 
70 /*
71  * These bits define what is in the elements of the "Raster" array
72  */
73 
74 #define RAST_FACE_EDGE 1
75 #define RAST_FACE_MASK 2
76 #define RAST_LHAND_EDGE 4
77 #define RAST_LHAND_MASK 8
78 #define RAST_BHAND_EDGE 16
79 #define RAST_BHAND_MASK 32
80 #define RAST_TEXT 64
81 #define RAST_TEXT_BACK 128
82 
83 /*
84  * Type definitions
85  */
86 
87 typedef struct{
88  unsigned char red, green, blue;
89 } color_t;
90 
91 /*
92  * Global variables
93  */
94 
96 color_t FaceColor;
97 color_t HandEdgeColor;
101 
107 
108 int XSize = XSIZE;
109 int YSize;
114 int Ticks = TICKS;
117 int Dots = DOTS;
123 
124 /*
125  * External globals.
126  */
127 
128 extern move_t Moves[];
129 extern int Base[];
130 
131 /*
132  * Forward declarations
133  */
134 
135 #ifdef USE_PROTOTYPES
136 void main(int argc, char *argv[]);
137 void ifImageSet(int i, int j, int value, color_t *color);
138 void drawHand(double place, double scale, double radius, int mask, int edge);
139 void rasterAddBits(int mask, int match, int value);
140 void polarLine(double r0, double a0, double r1, double a1, int arg1, int arg2);
141 void setDot(int x, int y, int arg1, int arg2);
142 int polarToX(double fRadius, double angle);
143 int polarToY(double fRadius, double angle);
144 double radians(double degrees);
145 rle_pixel **rasterAllocate(int height, int width);
146 void rasterWrite(FILE *fd);
147 void lineDots(int x0, int y0, int x1, int y1, void (*func)(), int arg1, int arg2);
148 void procargs(int argc, char *argv[]);
149 bool argGiven(char *argVar);
150 void usageExit(char *pgm);
151 void charMinMaxWidth(int ch, int *min, int *max);
152 void charMinMaxHeight(int ch, int *min, int *max);
153 char *formatInterp(CONST_DECL char *str);
154 void drawText(void);
155 void areaFlood(int firstX, int firstY, int mask, int match, int value);
156 void stackPush(int x, int y, int dir);
157 int stackPop(void);
158 #else
159 void main();
160 void ifImageSet();
161 void drawHand();
162 void rasterAddBits();
163 void polarLine();
164 void setDot();
165 int polarToX();
166 int polarToY();
167 double radians();
168 rle_pixel **rasterAllocate();
169 void rasterWrite();
170 void lineDots();
171 void procargs();
172 bool argGiven();
173 void usageExit();
174 void charMinMaxWidth();
175 void charMinMaxHeight();
176 char *formatInterp();
177 void drawText();
178 void areaFlood();
179 void stackPush();
180 int stackPop();
181 #endif
182 char **gargv;
183 
184 void
186 int argc;
187 char *argv[];
188 {
189  int i, j;
190  float theta;
191  time_t now;
192  struct tm *tm, *localtime();
193  bool haveFaceColor;
194  bool haveHandEdgeColor;
195  bool haveTextBackColor;
196 
197  gargv = argv;
198 
199  procargs(argc, argv);
200  YRadius = (YClockSize - Dots) / 2;
201  XRadius = (XSize - Dots) / 2;
203  if (!argGiven((char *) &LittleHandValue) || !argGiven((char *) &BigHandValue)) {
204  (void)time(&now);
205  tm = localtime(&now);
206 
207  if (!argGiven((char *) &BigHandValue))
208  BigHandValue = (float) tm->tm_min;
209  if (!argGiven((char *) &LittleHandValue))
210  LittleHandValue = (float) ((tm->tm_hour % 12)) + BigHandValue / 60.0;
211  }
212  /*
213  * Allocate the storage for the raster
214  */
215 
221 
222  /*
223  * Initialize the raster to the background color
224  */
225 
226  for (i = 0; i < YSize; i++) {
227  for (j = 0; j < XSize; j++) {
228  Raster[i][j] = 0;
229  }
230  }
231 
232  /*
233  * Draw the clock face as a circle with tick marks
234  */
235 
236  for (i = 0; i < 360; i++) {
237  polarLine(1.0, (float) i, 1.0, (float) (i + 1), RAST_FACE_EDGE, Dots);
238  }
239  for (i = 0; i < Ticks; i++) {
240  theta = (float) i *360.0 / (float) Ticks;
241 
242  polarLine(1.0, theta, 0.85, theta, RAST_FACE_EDGE, Dots);
243  }
244 
245  /*
246  * Compute the RAST_FACE_MASK portion - includes what is inside the
247  * dial face plus the dial face itself. So first flood the inside, and
248  * then OR in the stuff under the face lines
249  */
250 
253 
254  /*
255  * Draw the hands and the text...
256  */
257 
260  if (YTextSize > 0) {
261  drawText();
262  }
263  /*
264  * Compose the clock image from the generated raster and program
265  * arguments
266  */
267 
268  haveFaceColor = argGiven((char *)&FaceColor);
269  haveHandEdgeColor = argGiven((char *)&HandEdgeColor);
270  haveTextBackColor = argGiven((char *)&TextBackColor);
271  for (i = 0; i < YSize; i++) {
272  for (j = 0; j < XSize; j++) {
273  if (haveFaceColor) {
275  }
278  if (haveHandEdgeColor) {
280  }
281  if (haveTextBackColor) {
283  }
285 
286  /*
287  * Now compute the Alpha channel
288  */
289 
290  if ( (haveFaceColor && (Raster[i][j]&RAST_FACE_MASK)!=0)
292  || (haveTextBackColor && (Raster[i][j] & RAST_TEXT_BACK)!=0)
293  || ((Raster[i][j] & RAST_TEXT)!=0)) {
294  AlphaLine[i][j] = 255;
295  } else {
296  AlphaLine[i][j] = 0;
297  }
298  }
299  }
300 
301  /*
302  * Dump the raster file to stdout...
303  */
304 
305  rasterWrite(stdout);
306 
307  exit(0);
308 }
309 
310 void
312 int i, j, value;
313 color_t *color;
314 {
315  if (Raster[i][j] & value) {
316  RedLine[i][j] = color->red;
317  GreenLine[i][j] = color->green;
318  BlueLine[i][j] = color->blue;
319  }
320 }
321 
322 void
324 double place;
325 double scale;
326 double radius;
327 int mask, edge;
328 {
329  float angle;
330  angle = place / scale * 360;
331  polarLine(HANDWIDTH, angle+180.0, HANDWIDTH, angle-90.0, edge, 1);
332  polarLine(HANDWIDTH, angle-90.0, radius, angle, edge, 1);
333  polarLine(radius, angle, HANDWIDTH, angle+90.0, edge, 1);
334  polarLine(HANDWIDTH, angle+90.0, HANDWIDTH, angle+180.0, edge, 1);
335  areaFlood(polarToX(0.0, 0.0), polarToY(0.0, 0.0), edge, 0,
336  mask);
337  polarLine(HANDWIDTH, angle+180.0, HANDWIDTH, angle-90.0, edge, Dots);
338  polarLine(HANDWIDTH, angle-90.0, radius, angle, edge, Dots);
339  polarLine(radius, angle, HANDWIDTH, angle+90.0, edge, Dots);
340  polarLine(HANDWIDTH, angle+90.0, HANDWIDTH, angle+180.0, edge, Dots);
341  rasterAddBits(edge, edge, mask);
342 }
343 
344 void
346 int mask, match, value;
347 {
348  int i, j;
349 
350  for (i = 0 ; i < YSize; i++) {
351  for (j = 0; j < XSize; j++) {
352  if ( (Raster[i][j]&mask) == match )
353  Raster[i][j] |= value;
354  }
355  }
356 }
357 
358 void
360 double r0, a0, r1, a1;
361 int arg1, arg2;
362 {
364  polarToY(r0, a0),
365  polarToX(r1, a1),
366  polarToY(r1, a1),
367  setDot, arg1, arg2);
368 }
369 
370 /*
371  * setDot
372  * ------
373  *
374  * Draw a dot (actually a square) or a certain size. This is called from
375  * lineDots to draw the dots that comprise a line.
376  */
377 
378 void
380 int x, y, arg1, arg2;
381 {
382  int i, j;
383 
384 if(Debug)fprintf(stderr, "Setting %d, %d\n", x, y);
385  for (i = 0; i < arg2; i++) {
386  for (j = 0; j < arg2; j++) {
387  Raster[y+i][x+j] |= arg1;
388  }
389  }
390 }
391 
392 
393 /*
394  * polar conversion
395  * ----------------
396  *
397  * These routines convert from polar coordinates to cartesian coordinates in
398  * the clock part of the pixel rectangle.
399  */
400 
401 int
403 double fRadius;
404 double angle;
405 {
406  return (int)(fRadius * sin(radians(angle)) * XRadius) + XSize/2;
407 }
408 
409 int
411 double fRadius;
412 double angle;
413 {
414  return (int)(fRadius * cos(radians(angle)) * YRadius) + YRadius;
415 }
416 
417 double
419 double degrees;
420 {
421  return degrees/180.0 * 3.1415926;
422 }
423 
424 /*
425  * rasterAllocate
426  * --------------
427  *
428  * Allocate a raster for a single color.
429  */
430 
431 rle_pixel **
433 int height, width;
434 {
435  rle_pixel **new, *row;
436  int i;
437 
438  new = (rle_pixel **)calloc(height, sizeof(rle_pixel *));
439  row = (rle_pixel *)calloc(height*width, sizeof(rle_pixel));
440  for ( i=0 ; i<height ; i++) {
441  new[i] = row;
442  row += width;
443  }
444  return new;
445 }
446 
447 /*
448  * rasterWrite
449  * -----------
450  *
451  * Dump the entire raster to a Utah RLE format file.
452  */
453 
454 void
456 FILE *fd;
457 {
458  rle_hdr the_hdr;
459  rle_pixel *rows[4];
460  int i;
461 
462  the_hdr = *rle_hdr_init( (rle_hdr *)NULL );
463  rle_names( &the_hdr, cmd_name( gargv ), NULL, 0 );
464 
465  RLE_SET_BIT(the_hdr, RLE_ALPHA);
466  the_hdr.rle_file = fd;
467  the_hdr.xmax = XSize;
468  the_hdr.ymax = YSize;
469  the_hdr.alpha = 1;
470  rle_addhist( gargv, NULL, &the_hdr );
471 
472  rle_put_setup(&the_hdr);
473  for (i = 0; i < YSize; i++) {
474  rows[0] = AlphaLine[i];
475  if (DebugAlpha) {
476  rows[1] = AlphaLine[i];
477  rows[2] = AlphaLine[i];
478  rows[3] = AlphaLine[i];
479  } else {
480  rows[1] = RedLine[i];
481  rows[2] = GreenLine[i];
482  rows[3] = BlueLine[i];
483  }
484  rle_putrow(rows + 1, XSize, &the_hdr);
485  }
486  rle_close_f( the_hdr.rle_file );
487 }
488 
489 /*
490  * Bresenham's line drawing algorithm based on the general Bresenham
491  * line drawing algorithm described in Rogers "Procedural Elements for
492  * Computer Graphics" on page 40.
493  *
494  * Written by Nancy Blachman
495  * CS 248A, Winter
496  * Prof. Leo Guibas
497  * Stanford University
498  * January 13, 1987
499  *
500  * This is why RIACS sent Nancy to grad school!
501  */
502 
503 void
505 int x0, y0, x1, y1;
506 void (*func)();
507 int arg1, arg2;
508 {
509  int e, x, y, delta_x, delta_y, tmp;
510  bool interchg = FALSE;
511  int dir_x, dir_y;
512  int two_dy, two_dx; /* calculated outside of loop */
513  register int i;
514 
515 
516  if (x0 == x1 && y0 == y1) { /* is starting point = end point ? */
517  (*func)(x0, y0, arg1, arg2);
518  return;
519  }
520  x = x0;
521  y = y0;
522 
523  delta_x = x1 - x0;
524  delta_y = y1 - y0;
525 
526  delta_x = delta_x > 0 ? delta_x : -delta_x; /* absolute value,
527  * abs(x1-x0) */
528  delta_y = delta_y > 0 ? delta_y : -delta_y; /* absolute value,
529  * abs(y1-x0) */
530 
531  dir_x = (x1 - x0) > 0 ? 1 : -1; /* sign (x1 - x0) */
532  dir_y = (y1 - y0) > 0 ? 1 : -1; /* sign (y1 - y0) */
533 
534  if (delta_y > delta_x) {
535  tmp = delta_x;
536  delta_x = delta_y;
537  delta_y = tmp;
538  interchg = TRUE;
539  }
540  two_dx = 2 * delta_x;
541  two_dy = 2 * delta_y;
542 
543  e = two_dy - delta_x;
544  for (i = 1; i <= delta_x; ++i) {
545  (*func) (x, y, arg1, arg2);
546  while (e >= 0) {
547  if (interchg)
548  x += dir_x;
549  else
550  y += dir_y;
551  e -= two_dx;
552  }
553  if (interchg)
554  y += dir_y;
555  else
556  x += dir_x;
557  e += two_dy;
558  }
559 }
560 
561 /*
562  * procargs
563  * --------
564  *
565  * Argument line parser. This version is table driven and requires exact match
566  * on the argument switches.
567  */
568 
569 struct {
570  bool show;
571  CONST_DECL char *arg;
572  enum { INT, FLOAT, STRING, BOOL, COLOR, HELP, TEXT } type;
573  CONST_DECL char *description;
574  CONST_DECL char *value;
575  bool given;
576 } Args[] ={
577  { TRUE, "-x", INT, "Image width in pixels", (char *)&XSize },
578  { TRUE, "-cy", INT, "Clock image height in pixels", (char *)&YClockSize },
579  { TRUE, "-ty", INT, "Text image height in pixels", (char *)&YTextSize },
580  { TRUE, "-help", HELP, "Prints this help message", NULL },
581 
582  { TRUE, "-bv", FLOAT, "Big hand value", (char *)&BigHandValue },
583  { TRUE, "-bs", FLOAT, "Big hand full scale value", (char *)&BigHandScale },
584  { TRUE, "-lv", FLOAT, "Little hand value", (char *)&LittleHandValue },
585  { TRUE, "-ls", FLOAT, "Little hand full scale value", (char *)&LittleHandScale },
586  { TRUE, "-t", INT, "Number of ticks around the face", (char *)&Ticks },
587  { TRUE, "-lw", INT, "Line width in pixels", (char *)&Dots },
588 
589  { TRUE, "-fc", COLOR, "Clock face edges color", (char *)&FaceEdgeColor },
590  { TRUE, "-Fc", COLOR, "Clock face background color", (char *)&FaceColor },
591  { TRUE, "", TEXT, " - if omitted, then the clock is transparent" },
592  { TRUE, "-hc", COLOR, "Clock hands edges color", (char *)&HandEdgeColor },
593  { TRUE, "", TEXT, " - if omitted, no hand edges shown" },
594  { TRUE, "-Hc", COLOR, "Clock hands fill color", (char *)&HandColor },
595  { TRUE, "-tc", COLOR, "Text color", (char *)&TextColor},
596  { TRUE, "-Tc", COLOR, "Text background color", (char *)&TextBackColor},
597  { TRUE, "", TEXT, " - if omitted, then the text is transparent" },
598  { TRUE, "-tf", STRING, "Text area format string", (char *)&FormatString },
599  { FALSE, "-Xm", BOOL, "Output the alpha channel on RGB", (char *)&DebugAlpha },
600  { FALSE, "-D", BOOL, "Turn on debugging", (char *)&Debug },
601  { FALSE, NULL }
602 };
603 
604 void
606 int argc;
607 char *argv[];
608 {
609  int arg, i;
610  color_t *color;
611 
612  for ( arg = 1 ; arg<argc ; arg++) {
613  for ( i=0 ; Args[i].arg != NULL ; i++) {
614  if (Args[i].type != TEXT && strcmp(argv[arg], Args[i].arg) == 0) {
615  break;
616  }
617  }
618  if (Args[i].arg==NULL) {
619  fprintf(stderr, "Unknown argument: \"%s\"\n", argv[arg]);
620  usageExit(argv[0]);
621  }
622  Args[i].given = TRUE;
623  switch (Args[i].type) {
624  case HELP:
625  usageExit(argv[0]);
626  break;
627  case INT:
628  arg += 1;
629  *(int *)Args[i].value = atoi(argv[arg]);
630  break;
631  case FLOAT:
632  arg += 1;
633  *(float *)Args[i].value = atof(argv[arg]);
634  break;
635  case BOOL:
636  *(bool *)Args[i].value = TRUE;
637  break;
638  case STRING:
639  arg += 1;
640  *(char **)Args[i].value = (char *)malloc(strlen(argv[arg])+1);
641  strcpy(*(char **)Args[i].value, argv[arg]);
642  break;
643  case COLOR:
644  color = (color_t *)Args[i].value;
645  if ( arg+3 >= argc || !isdigit(argv[arg+1][0])
646  || !isdigit(argv[arg+2][0])
647  || !isdigit(argv[arg+3][0])) {
648  fprintf(stderr, "%s: %s takes three numeric arguments\n", argv[0],
649  Args[i].arg);
650  usageExit(argv[0]);
651  }
652  color->red = atoi(argv[arg+1]);
653  color->green = atoi(argv[arg+2]);
654  color->blue = atoi(argv[arg+3]);
655  arg += 3;
656  break;
657  default:
658  break;
659  }
660  }
661 }
663 char *argVar;
664 {
665  int i;
666 
667  for ( i=0 ; Args[i].arg != NULL ; i++) {
668  if (Args[i].value == argVar) {
669  return Args[i].given;
670  }
671  }
672  return FALSE;
673 }
674 
675 void
677 char *pgm;
678 {
679  int i;
680 
681  fprintf(stderr, "Usage: %s [args]\n", pgm);
682  for (i = 0; Args[i].arg != NULL; i++) {
683  if (Args[i].show) {
684  fprintf(stderr, "\t%s", Args[i].arg);
685  switch (Args[i].type) {
686  case INT:
687  fprintf(stderr, " INT");
688  break;
689  case FLOAT:
690  fprintf(stderr, " FLOAT");
691  break;
692  case BOOL:
693  break;
694  case STRING:
695  fprintf(stderr, " STR");
696  break;
697  case COLOR:
698  fprintf(stderr, " RED GREEN BLUE");
699  break;
700  default:
701  break;
702  }
703  fprintf(stderr, " ... %s\n", Args[i].description);
704  }
705  }
706  exit(1);
707 
708 }
709 
710 /*
711  * charMinMax{Width,Height}
712  * ------------------------
713  *
714  * Compute the minimum and maximum width and height of a character as defined
715  * in the font.
716  */
717 
718 void
720 int ch;
721 int *min, *max;
722 {
723  int epos, pos;
724 
725  if (!isprint(ch)) {
726  *min = *max = 0;
727  return;
728  }
729  if (ch == ' ') {
730  ch = 'n';
731  }
732  *min = 999;
733  *max = -999;
734  epos = Base[(int)ch - 33 + 1];
735  pos = Base[(int)ch - 33];
736  for (; pos < epos; pos++) {
737  if (Moves[pos].x > *max) {
738  *max = Moves[pos].x;
739  }
740  if (Moves[pos].x < *min) {
741  *min = Moves[pos].x;
742  }
743  }
744 }
745 
746 void
748 int ch;
749 int *min, *max;
750 {
751  int epos, pos;
752 
753  if (!isprint(ch)) {
754  *min = *max = 0;
755  return;
756  }
757  if (ch == ' ') {
758  ch = 'n';
759  }
760  *min = 999;
761  *max = -999;
762  epos = Base[(int)ch - 33 + 1];
763  pos = Base[(int)ch - 33];
764  for (; pos < epos; pos++) {
765  if (Moves[pos].y > *max) {
766  *max = Moves[pos].y;
767  }
768  if (Moves[pos].y < *min) {
769  *min = Moves[pos].y;
770  }
771  }
772 }
773 
774 /*
775  * formatInterp
776  * ------------
777  *
778  * Interpret the format string - returns the value string as specified.
779  */
780 
781 char *
783 CONST_DECL char *str;
784 {
785  char *buf, *bufp;
786  int state;
787  static char outBuf[1024];
788  char tmpBuf[1024];
789 
790  buf = (char *)malloc(strlen(str)*2+1);
791  bufp = buf;
792  state = 0;
793  strcpy(outBuf, "");
794  while ( *str != 0) {
795  switch (state) {
796  case 0:
797  *bufp++ = *str;
798  if (*str == '%') {
799  state = 1;
800  }
801  break;
802  case 1:
803  if (isdigit(*str) || *str == '.') {
804  *bufp++ = *str;
805  } else {
806  if ( *str=='B' || *str=='L') {
807  *bufp++ = 'f';
808  *bufp = 0;
809  sprintf(tmpBuf, buf, *str == 'B' ? (float)BigHandValue
810  : (float)LittleHandValue);
811  } else if ( *str=='b' || *str=='l') {
812  *bufp++ = 'd';
813  *bufp = 0;
814  sprintf(tmpBuf, buf, *str == 'b' ? (int)BigHandValue
815  : (int)LittleHandValue);
816  } else {
817  *bufp++ = *str;
818  *bufp = 0;
819  strcpy(tmpBuf, buf);
820  }
821  strcat(outBuf, tmpBuf);
822  bufp = buf;
823  state = 0;
824  }
825  break;
826  }
827  str++;
828  }
829  *bufp = 0;
830  strcat(outBuf, buf);
831  free(buf);
832  return outBuf;
833 }
834 
835 /*
836  * drawText
837  * --------
838  *
839  * Draw vectors for the given tect string, in the TEXT area of the raster.
840  */
841 
842 #define CHARPAD 25
843 
844 void
845 drawText()
846 {
847  char *string;
848  int i, j, xsize, ysize, min, max, basex;
849  int curx, cury, x, y, pos, epos, charBasex;
850  float scale, scalex;
851 
853  xsize = CHARPAD+Dots;
854  ysize = 0;
855  for (i = 0; string[i] != 0; i++) {
856  charMinMaxWidth(string[i], &min, &max);
857  xsize += (max - min) + CHARPAD+Dots;
858  charMinMaxHeight(string[i], &min, &max);
859  if (ysize < (max - min)+Dots) {
860  ysize = max - min+Dots;
861  }
862  }
863  scale = (float) YTextSize / (float) ysize;
864  scalex = (float) XSize / (float) xsize;
865  if (scale > scalex) {
866  scale = scalex;
867  }
868  basex = (XSize - (int) ((float)xsize * scale)) / 2;
869  curx = cury = 0;
870  charBasex = CHARPAD;
871  for (i = 0; string[i] != 0; i++) {
872  if (isprint(string[i]) && string[i] != ' ') {
873  charMinMaxWidth(string[i], &min, &max);
874  epos = Base[((int) (string[i])) - 33 + 1];
875  for (pos = Base[(int) string[i] - 33]; pos < epos; pos++) {
876  x = basex + (int) (scale * (charBasex + Moves[pos].x + (-min)));
877  y = (int) (scale * Moves[pos].y);
878  if (Moves[pos].type == 'n') {
879  lineDots(curx, YClockSize + Dots + 1 + cury, x, YClockSize + Dots + 1 + y, setDot, RAST_TEXT, Dots);
880  }
881  curx = x;
882  cury = y;
883  }
884  }
885  charBasex += (max-min) + CHARPAD + Dots;
886  }
887  x = basex + (int)(scale * charBasex);
888  if (x > XSize) {
889  x = XSize;
890  }
891  y = scale * ysize + YClockSize+Dots+1;
892  if (y+Dots > YSize) {
893  y = YSize-Dots;
894  }
895  for (i = YClockSize+Dots; i < y+Dots ; i++) {
896  for (j = basex; j < x; j++) {
897  Raster[i][j] |= RAST_TEXT_BACK;
898  }
899  }
900 }
901 
902 /*
903  * areaFlood
904  * ---------
905  *
906  * A flooding algorithm for painting regions of the clock
907  */
908 
909 typedef struct {
910  short x, y;
911  int dir;
912 } _urt_stack;
913 
914 #define NORTH 0
915 #define WEST 1
916 #define SOUTH 2
917 #define EAST 3
918 struct {
919  _urt_stack *s;
920  int top;
921  int allocked;
922 } Stack;
923 
924 int XMove[4] = {0, 1, 0, -1};
925 int YMove[4] = {1, 0, -1, 0};
926 
927 void
929 int firstX, firstY;
930 int mask, match, value;
931 {
932  register _urt_stack *sp;
933 
934  Stack.s = (_urt_stack *) calloc(256, sizeof(_urt_stack));
935  Stack.allocked = 256;
936  Stack.top = -1;
937  stackPush(firstX, firstY, NORTH);
938 
939  while (Stack.top >= 0) {
940  sp = &Stack.s[Stack.top];
941  if ((Raster[sp->y][sp->x]&mask)==match && (Raster[sp->y][sp->x]&value)!=value) {
942  Raster[sp->y][sp->x] |= value;
943  if (Debug)
944  fprintf(stderr, "Marking %d, %d at stack %d\n", sp->x, sp->y, Stack.top);
945  stackPush(sp->x + XMove[sp->dir], sp->y + YMove[sp->dir],
946  NORTH);
947  } else {
948  do {
949  if (stackPop())
950  break;
951  sp = &Stack.s[Stack.top];
952  sp->dir++;
953  } while (sp->dir >= 4);
954  if (Stack.top >= 0)
955  stackPush(sp->x + XMove[sp->dir], sp->y + YMove[sp->dir],
956  NORTH);
957  }
958  }
959 }
960 
961 void
963 int x, y, dir;
964 {
965  if (++Stack.top >= Stack.allocked) {
966  Stack.allocked += 256;
967  Stack.s = (_urt_stack *) realloc(Stack.s, Stack.allocked * sizeof(_urt_stack));
968 if(Debug)fprintf(stderr, "Stack growing to %d\n", Stack.allocked);
969  }
970  Stack.s[Stack.top].x = x;
971  Stack.s[Stack.top].y = y;
972  Stack.s[Stack.top].dir = dir;
973 }
974 
975 int
976 stackPop()
977 {
978  Stack.top -= 1;
979  return Stack.top < 0;
980 }
#define RLE_SET_BIT(glob, bit)
Definition: rle.h:122
int XRadius
Definition: rleClock.c:112
color_t FaceColor
Definition: rleClock.c:96
short y
Definition: rleClock.c:910
#define CHARPAD
Definition: rleClock.c:842
const char * FormatString
Definition: rleClock.c:122
float LittleHandScale
Definition: rleClock.c:120
#define HANDWIDTH
Definition: rleClock.c:62
#define FORMATSTRING
Definition: rleClock.c:55
int Ticks
Definition: rleClock.c:114
#define USE_PROTOTYPES
Definition: rle_config.h:22
void stackPush(int x, int y, int dir)
Definition: rleClock.c:962
#define RAST_LHAND_EDGE
Definition: rleClock.c:76
void drawHand(double place, double scale, double radius, int mask, int edge)
Definition: rleClock.c:323
void rle_names(rle_hdr *the_hdr, const char *pgmname, const char *fname, int img_num)
Definition: rle_hdr.c:48
void rasterAddBits(int mask, int match, int value)
Definition: rleClock.c:345
int YClockSize
Definition: rleClock.c:110
#define HAND_COLOR
Definition: rleClock.c:57
int YTextSize
Definition: rleClock.c:111
bool DebugAlpha
Definition: rleClock.c:115
char * cmd_name(char **argv)
Definition: cmd_name.c:31
unsigned char green
Definition: rleClock.c:88
unsigned char blue
Definition: rleClock.c:88
#define RAST_LHAND_MASK
Definition: rleClock.c:77
void rle_close_f(FILE *fd)
Definition: rle_open_f.c:244
void polarLine(double r0, double a0, double r1, double a1, int arg1, int arg2)
Definition: rleClock.c:359
void main(int argc, char **argv)
Definition: aliastorle.c:121
#define RAST_BHAND_EDGE
Definition: rleClock.c:78
#define FALSE
Definition: giftorle.c:39
short x
Definition: rleClock.c:910
int XMove[4]
Definition: rleClock.c:924
void charMinMaxWidth(int ch, int *min, int *max)
Definition: rleClock.c:719
int XSize
Definition: rleClock.c:108
int polarToY(double fRadius, double angle)
Definition: rleClock.c:410
#define FACE_EDGE_COLOR
Definition: rleClock.c:56
int polarToX(double fRadius, double angle)
Definition: rleClock.c:402
int Base[]
Definition: font.c:303
rle_pixel ** Raster
Definition: rleClock.c:105
int YRadius
Definition: rleClock.c:113
int YSize
Definition: rleClock.c:109
char * formatInterp(char *str) const
Definition: rleClock.c:782
char bool
Definition: rleClock.c:68
void charMinMaxHeight(int ch, int *min, int *max)
Definition: rleClock.c:747
color_t TextBackColor
Definition: rleClock.c:100
#define RAST_BHAND_MASK
Definition: rleClock.c:79
void rle_putrow(rows, int rowlen, rle_hdr *the_hdr)
Definition: rle_putrow.c:96
int xmax
Definition: rle.h:100
#define BIGHANDSCALE
Definition: rleClock.c:60
void rasterWrite(FILE *fd)
Definition: rleClock.c:455
#define RAST_FACE_EDGE
Definition: rleClock.c:74
void lineDots(int x0, int y0, int x1, int y1, void(*func)(), int arg1, int arg2)
Definition: rleClock.c:504
rle_pixel ** GreenLine
Definition: rleClock.c:103
color_t HandEdgeColor
Definition: rleClock.c:97
#define RAST_TEXT_BACK
Definition: rleClock.c:81
color_t FaceEdgeColor
Definition: rleClock.c:95
void usageExit(char *pgm)
Definition: rleClock.c:676
float BigHandValue
Definition: rleClock.c:118
rle_pixel ** RedLine
Definition: rleClock.c:102
void areaFlood(int firstX, int firstY, int mask, int match, int value)
Definition: rleClock.c:928
#define CONST_DECL
Definition: rle_config.h:42
void rle_addhist(argv, rle_hdr *in_hdr, rle_hdr *out_hdr)
Definition: rle_addhist.c:54
#define TEXT_COLOR
Definition: rleClock.c:58
#define TRUE
Definition: giftorle.c:38
void procargs(int argc, argv)
Definition: rleClock.c:605
#define RAST_FACE_MASK
Definition: rleClock.c:75
bool argGiven(char *argVar)
Definition: rleClock.c:662
char ** gargv
Definition: unslice.c:52
#define DOTS
Definition: rleClock.c:54
#define LITTLEHANDSCALE
Definition: rleClock.c:59
#define YTEXTSIZE
Definition: rleClock.c:51
char type
Definition: font.h:2
rle_pixel ** BlueLine
Definition: rleClock.c:104
int ymax
Definition: rle.h:100
float LittleHandValue
Definition: rleClock.c:119
move_t Moves[]
Definition: font.c:2
unsigned char rle_pixel
Definition: rle.h:56
void rle_put_setup(rle_hdr *the_hdr)
Definition: rle_putrow.c:453
color_t TextColor
Definition: rleClock.c:99
double radians(double degrees)
Definition: rleClock.c:418
#define TICKS
Definition: rleClock.c:53
rle_pixel ** AlphaLine
Definition: rleClock.c:106
int alpha
Definition: rle.h:100
#define RLE_ALPHA
Definition: rle.h:65
bool Debug
Definition: rleClock.c:116
int YMove[4]
Definition: rleClock.c:925
int Dots
Definition: rleClock.c:117
rle_pixel ** rasterAllocate(int height, int width)
Definition: rleClock.c:432
#define YCLOCKSIZE
Definition: rleClock.c:52
color_t HandColor
Definition: rleClock.c:98
float BigHandScale
Definition: rleClock.c:121
int x
Definition: font.h:3
rle_hdr * rle_hdr_init(rle_hdr *the_hdr)
Definition: rle_hdr.c:267
void ifImageSet(int i, int j, int value, color_t *color)
Definition: rleClock.c:311
static char rcsid[]
Definition: rleClock.c:30
#define NORTH
Definition: rleClock.c:914
#define XSIZE
Definition: rleClock.c:50
FILE * rle_file
Definition: rle.h:114
int y
Definition: font.h:3
#define RAST_TEXT
Definition: rleClock.c:80
void setDot(int x, int y, int arg1, int arg2)
Definition: rleClock.c:379
unsigned char red
Definition: rleClock.c:88