ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 1.1
Committed: Thu Feb 2 10:49:28 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# User Rev Content
1 greg 1.1 /* Copyright (c) 1987 Regents of the University of California */
2    
3     #ifndef lint
4     static char SCCSid[] = "$SunId$ LBL";
5     #endif
6    
7     /*
8     * psign.c - produce picture from text.
9     *
10     * 7/1/87
11     */
12    
13     #include <stdio.h>
14    
15     #include "color.h"
16    
17     #define MAXLINE 512 /* longest allowable line */
18    
19     char *fontfile = "/usr/local/lib/ray/helvet.fnt"; /* our font file */
20    
21     COLR bgcolr = WHTCOLR; /* background color */
22     COLR fgcolr = BLKCOLR; /* foreground color */
23    
24     int direct = 'r'; /* direction (right, up, left, down) */
25    
26     int cheight = 32; /* character height */
27     double aspect = 1.67; /* height/width character aspect */
28     int cwidth; /* computed character width */
29    
30     unsigned char *ourbitmap; /* our output bitmap */
31     int xsiz, ysiz; /* bitmap dimensions */
32     int xdim; /* size of horizontal scan (bytes) */
33    
34     #define bitop(x,y,op) (ourbitmap[(y)*xdim+((x)>>3)] op (1<<((x)&7)))
35     #define tstbit(x,y) bitop(x,y,&)
36     #define setbit(x,y) bitop(x,y,|=)
37     #define clrbit(x,y) bitop(x,y,&=~)
38     #define tglbit(x,y) bitop(x,y,^=)
39    
40     typedef unsigned char GLYPH;
41    
42     GLYPH *ourfont[128]; /* our font */
43    
44     typedef struct line {
45     char *s; /* line w/o LF */
46     struct line *next; /* next line up */
47     } LINE;
48    
49     LINE *ourtext; /* our text */
50     int nlines, maxline; /* text dimensions */
51    
52     char *malloc(), *calloc();
53    
54    
55     main(argc, argv)
56     int argc;
57     char *argv[];
58     {
59     double atof();
60     int an;
61    
62     for (an = 1; an < argc && argv[an][0] == '-'; an++)
63     switch (argv[an][1]) {
64     case 'c': /* color */
65     switch (argv[an][2]) {
66     case 'f': /* foreground */
67     setcolr(fgcolr, atof(argv[an+1]),
68     atof(argv[an+2]),
69     atof(argv[an+3]));
70     an += 3;
71     break;
72     case 'b': /* background */
73     setcolr(bgcolr, atof(argv[an+1]),
74     atof(argv[an+2]),
75     atof(argv[an+3]));
76     an += 3;
77     break;
78     default:
79     goto unkopt;
80     }
81     break;
82     case 'f': /* font */
83     fontfile = argv[++an];
84     break;
85     case 'd': /* direction */
86     switch (argv[an][2]) {
87     case 'r': /* right */
88     case 'u': /* up */
89     case 'l': /* left */
90     case 'd': /* down */
91     direct = argv[an][2];
92     break;
93     default:
94     goto unkopt;
95     }
96     break;
97     case 'h': /* height of characters */
98     cheight = atoi(argv[++an]);
99     break;
100     case 'a': /* aspect ratio */
101     aspect = atof(argv[++an]);
102     break;
103     default:;
104     unkopt:
105     fprintf(stderr, "%s: unknown option: %s\n",
106     argv[0], argv[an]);
107     exit(1);
108     }
109     /* get text */
110     if (an == argc)
111     gettext(stdin);
112     else
113     arg_text(argc-an, argv+an);
114    
115     /* create bit map */
116     makemap();
117     /* load font file */
118     loadfont();
119     /* convert text to bitmap */
120     maptext();
121     /* print header */
122     printargs(argc, argv, stdout);
123     printf("\n\n");
124     /* write out bitmap */
125     writemap(stdout);
126    
127     exit(0);
128     }
129    
130    
131     makemap() /* create the bit map */
132     {
133     cwidth = cheight/aspect + 0.5;
134     if (direct == 'r' || direct == 'l') {
135     xsiz = maxline*cwidth;
136     ysiz = nlines*cheight;
137     } else { /* reverse orientation */
138     xsiz = nlines*cheight;
139     ysiz = maxline*cwidth;
140     }
141     xdim = (xsiz+7)/8;
142     ourbitmap = (BYTE *)calloc(ysiz, xdim);
143     if (ourbitmap == NULL) {
144     fprintf(stderr, "out of memory in makemap\n");
145     exit(1);
146     }
147     }
148    
149    
150     loadfont() /* load the font file */
151     {
152     FILE *fp;
153     char *err;
154     int gn, ngv, gv;
155     register GLYPH *g;
156    
157     if ((fp = fopen(fontfile, "r")) == NULL) {
158     fprintf(stderr, "cannot open font file \"%s\"\n",
159     fontfile);
160     exit(1);
161     }
162     while (fscanf(fp, "%d", &gn) == 1) { /* get each glyph */
163     if (gn < 0 || gn > 127) {
164     err = "illegal";
165     goto fonterr;
166     }
167     if (ourfont[gn] != NULL) {
168     err = "duplicate";
169     goto fonterr;
170     }
171     if (fscanf(fp, "%d", &ngv) != 1 ||
172     ngv < 0 || ngv > 255) {
173     err = "bad # vertices for";
174     goto fonterr;
175     }
176     g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH));
177     if (g == NULL)
178     goto memerr;
179     ourfont[gn] = g;
180     *g++ = ngv;
181     ngv *= 2;
182     while (ngv--) {
183     if (fscanf(fp, "%d", &gv) != 1 ||
184     gv < 0 || gv > 255) {
185     err = "bad vertex for";
186     goto fonterr;
187     }
188     *g++ = gv;
189     }
190     }
191     fclose(fp);
192     return;
193     fonterr:
194     fprintf(stderr, "%s character (%d) in font file \"%s\"\n",
195     err, gn, fontfile);
196     exit(1);
197     memerr:
198     fprintf(stderr, "out of memory in loadfont\n");
199     exit(1);
200     }
201    
202    
203     gettext(fp) /* get text from a file */
204     FILE *fp;
205     {
206     char *fgets();
207     char buf[MAXLINE];
208     register LINE *curl;
209     int len;
210    
211     maxline = 0;
212     nlines = 0;
213     while (fgets(buf, MAXLINE, fp) != NULL) {
214     curl = (LINE *)malloc(sizeof(LINE));
215     if (curl == NULL)
216     goto memerr;
217     len = strlen(buf);
218     curl->s = malloc(len--);
219     if (curl->s == NULL)
220     goto memerr;
221     strncpy(curl->s, buf, len);
222     curl->s[len] = '\0';
223     curl->next = ourtext;
224     ourtext = curl;
225     if (len > maxline)
226     maxline = len;
227     nlines++;
228     }
229     return;
230     memerr:
231     fprintf(stderr, "out of memory in gettext\n");
232     exit(1);
233     }
234    
235    
236     arg_text(ac, av) /* get text from arguments */
237     int ac;
238     char *av[];
239     {
240     register char *cp;
241    
242     ourtext = (LINE *)malloc(sizeof(LINE));
243     if (ourtext == NULL)
244     goto memerr;
245     ourtext->s = malloc(MAXLINE);
246     if (ourtext->s == NULL)
247     goto memerr;
248     for (cp = ourtext->s; ac-- > 0; av++) {
249     strcpy(cp, *av);
250     cp += strlen(*av);
251     *cp++ = ' ';
252     }
253     *--cp = '\0';
254     ourtext->next = NULL;
255     maxline = strlen(ourtext->s);
256     nlines = 1;
257     return;
258     memerr:
259     fprintf(stderr, "out of memory in arg_text\n");
260     exit(1);
261     }
262    
263    
264     maptext() /* map our text */
265     {
266     register LINE *curl;
267     int l;
268     register int c;
269    
270     for (l = 0, curl = ourtext; curl != NULL; l++, curl = curl->next)
271     for (c = strlen(curl->s)-1; c >= 0; c--)
272     mapglyph(ourfont[curl->s[c]], c, l);
273     }
274    
275    
276     mapglyph(gl, tx0, ty0) /* convert a glyph */
277     register GLYPH *gl;
278     int tx0, ty0;
279     {
280     int n;
281     int p0[2], p1[2];
282    
283     if (gl == NULL)
284     return;
285    
286     tx0 <<= 8; ty0 <<= 8;
287     n = *gl++;
288     mapcoord(p0, gl[2*n-2]+tx0, gl[2*n-1]+ty0);
289     while (n--) {
290     mapcoord(p1, gl[0]+tx0, gl[1]+ty0);
291     mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
292     p0[0] = p1[0]; p0[1] = p1[1];
293     gl += 2;
294     }
295     }
296    
297    
298     mapcoord(p, tx, ty) /* map text to picture coordinates */
299     int p[2], tx, ty;
300     {
301     tx = (long)tx*cwidth >> 8;
302     ty = (long)ty*cheight >> 8;
303    
304     switch (direct) {
305     case 'r': /* right */
306     p[0] = tx;
307     p[1] = ty;
308     return;
309     case 'u': /* up */
310     p[0] = xsiz-1-ty;
311     p[1] = tx;
312     return;
313     case 'l': /* left */
314     p[0] = xsiz-1-tx;
315     p[1] = ysiz-1-ty;
316     return;
317     case 'd': /* down */
318     p[0] = ty;
319     p[1] = ysiz-1-tx;
320     return;
321     }
322     }
323    
324    
325     mapedge(x, y, run, rise) /* map an edge */
326     register int x, y;
327     int run, rise;
328     {
329     int xstep;
330     int rise2, run2;
331     int n;
332    
333     if (rise == 0)
334     return;
335     /* always draw up */
336     if (rise < 0) {
337     x += run;
338     y += rise;
339     rise = -rise;
340     run = -run;
341     }
342     if (run < 0) {
343     xstep = -1;
344     run = -run;
345     } else
346     xstep = 1;
347     n = rise;
348     run2 = rise2 = 0;
349     while (n)
350     if (rise2 >= run2) {
351     tglbit(x, y);
352     n--;
353     y++;
354     run2 += run;
355     } else {
356     x += xstep;
357     rise2 += rise;
358     }
359     }
360    
361    
362     writemap(fp) /* write out bitmap */
363     FILE *fp;
364     {
365     COLR *scanout;
366     int y;
367     register int x;
368     register int inglyph;
369    
370     fprintf(fp, "-Y %d +X %d\n", ysiz, xsiz);
371    
372     scanout = (COLR *)malloc(xsiz*sizeof(COLR));
373     if (scanout == NULL) {
374     fprintf(stderr, "out of memory in writemap\n");
375     exit(1);
376     }
377     for (y = ysiz-1; y >= 0; y--) {
378     inglyph = 0;
379     for (x = 0; x < xsiz; x++) {
380     if (tstbit(x, y))
381     inglyph ^= 1;
382     if (inglyph)
383     copycolr(scanout[x], fgcolr);
384     else
385     copycolr(scanout[x], bgcolr);
386     }
387     if (fwritecolrs(scanout, xsiz, fp) < 0) {
388     fprintf(stderr, "write error in writemap\n");
389     exit(1);
390     }
391     }
392     free((char *)scanout);
393     }
394    
395    
396     printargs(ac, av, fp) /* print arguments to a file */
397     int ac;
398     char **av;
399     FILE *fp;
400     {
401     while (ac-- > 0) {
402     fputs(*av++, fp);
403     putc(' ', fp);
404     }
405     }