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

# Content
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 }