ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.22
Committed: Mon Jun 30 14:59:12 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.21: +6 -2 lines
Log Message:
Replaced most outdated BSD function calls with their posix equivalents, and cleaned up a few other platform dependencies.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: psign.c,v 2.21 2003/06/21 15:05:01 greg Exp $";
3 #endif
4 /*
5 * psign.c - produce picture from text.
6 *
7 * 7/1/87
8 */
9
10 #include "copyright.h"
11
12 #include <string.h>
13
14 #include "standard.h"
15 #include "platform.h"
16 #include "color.h"
17 #include "font.h"
18
19 #ifndef SSS
20 #define SSS 3 /* super-sample size */
21 #endif
22
23 #define MAXLINE 512 /* longest allowable line */
24
25 char *fontfile = "helvet.fnt"; /* our font file */
26
27 COLOR bgcolor = WHTCOLOR; /* background color */
28 COLOR fgcolor = BLKCOLOR; /* foreground color */
29
30 int direct = 'r'; /* direction (right, up, left, down) */
31
32 int cheight = 32*SSS; /* character height */
33 double aspect = 1.67; /* height/width character aspect */
34 double spacing = 0.0; /* character spacing */
35 int cwidth; /* computed character width */
36
37 unsigned char *ourbitmap; /* our output bitmap */
38 int xsiz, ysiz; /* bitmap dimensions */
39 int xdim; /* size of horizontal scan (bytes) */
40
41 /* conflicting def's in param.h */
42 #undef tstbit
43 #undef setbit
44 #undef clrbit
45 #undef tglbit
46
47 #define bitop(x,y,op) (ourbitmap[(y)*xdim+((x)>>3)] op (1<<((x)&7)))
48 #define tstbit(x,y) bitop(x,y,&)
49 #define setbit(x,y) bitop(x,y,|=)
50 #define clrbit(x,y) bitop(x,y,&=~)
51 #define tglbit(x,y) bitop(x,y,^=)
52
53 FONT *ourfont; /* our font */
54
55 typedef struct line {
56 char *s; /* line w/o LF */
57 short *sp; /* character spacing */
58 struct line *next; /* next line up */
59 } LINE;
60
61 LINE *ourtext; /* our text */
62 int nlines, maxline; /* text dimensions */
63 int maxwidth; /* maximum line width (dvi) */
64
65
66 main(argc, argv)
67 int argc;
68 char *argv[];
69 {
70 int an;
71 SET_FILE_BINARY(stdout);
72 for (an = 1; an < argc && argv[an][0] == '-'; an++)
73 switch (argv[an][1]) {
74 case 'c': /* color */
75 switch (argv[an][2]) {
76 case 'f': /* foreground */
77 setcolor(fgcolor, atof(argv[an+1]),
78 atof(argv[an+2]),
79 atof(argv[an+3]));
80 an += 3;
81 break;
82 case 'b': /* background */
83 setcolor(bgcolor, atof(argv[an+1]),
84 atof(argv[an+2]),
85 atof(argv[an+3]));
86 an += 3;
87 break;
88 default:
89 goto unkopt;
90 }
91 break;
92 case 'f': /* font */
93 fontfile = argv[++an];
94 break;
95 case 'd': /* direction */
96 switch (argv[an][2]) {
97 case 'r': /* right */
98 case 'u': /* up */
99 case 'l': /* left */
100 case 'd': /* down */
101 direct = argv[an][2];
102 break;
103 default:
104 goto unkopt;
105 }
106 break;
107 case 'x': /* x resolution */
108 xsiz = atoi(argv[++an])*SSS;
109 break;
110 case 'y':
111 ysiz = atoi(argv[++an])*SSS;
112 break;
113 case 'h': /* height of characters */
114 cheight = atoi(argv[++an])*SSS;
115 break;
116 case 'a': /* aspect ratio */
117 aspect = atof(argv[++an]);
118 break;
119 case 's': /* spacing */
120 spacing = atof(argv[++an]);
121 break;
122 default:;
123 unkopt:
124 fprintf(stderr, "%s: unknown option: %s\n",
125 argv[0], argv[an]);
126 exit(1);
127 }
128 /* load font file */
129 ourfont = getfont(fontfile);
130 /* get text */
131 if (an == argc)
132 gettext(stdin);
133 else
134 arg_text(argc-an, argv+an);
135
136 /* create bit map */
137 makemap();
138 /* convert text to bitmap */
139 maptext();
140 /* print header */
141 newheader("RADIANCE", stdout);
142 printargs(argc, argv, stdout);
143 fputformat(COLRFMT, stdout);
144 putchar('\n');
145 /* write out bitmap */
146 writemap(stdout);
147
148 exit(0);
149 }
150
151
152 makemap() /* create the bit map */
153 {
154 double pictaspect;
155
156 if (direct == 'r' || direct == 'l') {
157 if (xsiz <= 0) {
158 cwidth = cheight/aspect + 0.5;
159 xsiz = (long)maxwidth*cwidth >> 8;
160 ysiz = nlines*cheight;
161 } else if (aspect > FTINY) {
162 if (ysiz <= 0)
163 ysiz = cheight*nlines;
164 pictaspect = 256*nlines*aspect/maxwidth;
165 if (pictaspect*xsiz < ysiz)
166 ysiz = pictaspect*xsiz + 0.5;
167 else
168 xsiz = ysiz/pictaspect + 0.5;
169 cheight = ysiz/nlines;
170 cwidth = cheight/aspect;
171 } else {
172 if (ysiz <= 0)
173 ysiz = cheight*nlines;
174 pictaspect = (double)ysiz/xsiz;
175 aspect = pictaspect*maxwidth/(256*nlines);
176 cheight = ysiz/nlines;
177 cwidth = cheight/aspect;
178 }
179 } else { /* reverse orientation */
180 if (ysiz <= 0) {
181 cwidth = cheight/aspect + 0.5;
182 xsiz = nlines*cheight;
183 ysiz = (long)maxwidth*cwidth >> 8;
184 } else if (aspect > FTINY) {
185 if (xsiz <= 0)
186 xsiz = cheight*nlines;
187 pictaspect = maxwidth/(256*nlines*aspect);
188 if (pictaspect*xsiz < ysiz)
189 ysiz = pictaspect*xsiz + 0.5;
190 else
191 xsiz = ysiz/pictaspect + 0.5;
192 cheight = xsiz/nlines;
193 cwidth = cheight/aspect;
194 } else {
195 if (xsiz <= 0)
196 xsiz = cheight*nlines;
197 pictaspect = (double)ysiz/xsiz;
198 aspect = maxwidth/(256*nlines*pictaspect);
199 cheight = xsiz/nlines;
200 cwidth = cheight/aspect;
201 }
202 }
203 if (xsiz % SSS)
204 xsiz += SSS - xsiz%SSS;
205 if (ysiz % SSS)
206 ysiz += SSS - ysiz%SSS;
207 xdim = (xsiz+7)/8;
208 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
209 if (ourbitmap == NULL)
210 error(SYSTEM, "Out of memory in makemap");
211 memset((char *)ourbitmap, '\0', ysiz*xdim);
212 }
213
214
215 gettext(fp) /* get text from a file */
216 FILE *fp;
217 {
218 char buf[MAXLINE];
219 register LINE *curl;
220 int len;
221
222 maxline = 0;
223 maxwidth = 0;
224 nlines = 0;
225 while (fgets(buf, MAXLINE, fp) != NULL) {
226 curl = (LINE *)malloc(sizeof(LINE));
227 if (curl == NULL)
228 goto memerr;
229 len = strlen(buf);
230 curl->s = (char *)malloc(len);
231 curl->sp = (short *)malloc(sizeof(short)*len--);
232 if (curl->s == NULL | curl->sp == NULL)
233 goto memerr;
234 if (len > maxline)
235 maxline = len;
236 strncpy(curl->s, buf, len);
237 curl->s[len] = '\0';
238 if (spacing < -1./256.)
239 len = squeeztext(curl->sp, curl->s, ourfont,
240 (int)(spacing*-256.));
241 else if (spacing > 1./256.)
242 len = proptext(curl->sp, curl->s, ourfont,
243 (int)(spacing*256.), 3);
244 else
245 len = uniftext(curl->sp, curl->s, ourfont);
246 if (len > maxwidth)
247 maxwidth = len;
248 curl->next = ourtext;
249 ourtext = curl;
250 nlines++;
251 }
252 return;
253 memerr:
254 error(SYSTEM, "Out of memory in gettext");
255 }
256
257
258 arg_text(ac, av) /* get text from arguments */
259 int ac;
260 char *av[];
261 {
262 register char *cp;
263
264 ourtext = (LINE *)malloc(sizeof(LINE));
265 if (ourtext == NULL)
266 goto memerr;
267 ourtext->s = (char *)malloc(MAXLINE);
268 if (ourtext->s == NULL)
269 goto memerr;
270 for (cp = ourtext->s; ac-- > 0; av++) {
271 strcpy(cp, *av);
272 cp += strlen(*av);
273 *cp++ = ' ';
274 }
275 *--cp = '\0';
276 ourtext->next = NULL;
277 maxline = strlen(ourtext->s);
278 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
279 if (ourtext->sp == NULL)
280 goto memerr;
281 if (spacing < -1./256.)
282 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
283 (int)(spacing*-256.));
284 else if (spacing > 1./256.)
285 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
286 (int)(spacing*256.), 3);
287 else
288 maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
289 nlines = 1;
290 return;
291 memerr:
292 error(SYSTEM, "Out of memory in arg_text");
293 }
294
295
296 maptext() /* map our text */
297 {
298 register LINE *curl;
299 int l, len;
300 register int i, c;
301
302 for (l = 0, curl = ourtext; curl != NULL; l += 256, curl = curl->next) {
303 len = strlen(curl->s); c = 0;
304 for (i = 0; i < len; i++) {
305 c += curl->sp[i];
306 mapglyph(ourfont->fg[curl->s[i]&0xff], c, l);
307 }
308 }
309 }
310
311
312 mapglyph(gl, tx0, ty0) /* convert a glyph */
313 GLYPH *gl;
314 int tx0, ty0;
315 {
316 int n;
317 register GORD *gp;
318 int p0[2], p1[2];
319
320 if (gl == NULL)
321 return;
322
323 n = gl->nverts;
324 gp = gvlist(gl);
325 mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
326 while (n--) {
327 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
328 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
329 p0[0] = p1[0]; p0[1] = p1[1];
330 gp += 2;
331 }
332 }
333
334
335 mapcoord(p, tx, ty) /* map text to picture coordinates */
336 int p[2], tx, ty;
337 {
338 tx = (long)tx*cwidth >> 8;
339 ty = (long)ty*cheight >> 8;
340
341 switch (direct) {
342 case 'r': /* right */
343 p[0] = tx;
344 p[1] = ty;
345 return;
346 case 'u': /* up */
347 p[0] = xsiz-1-ty;
348 p[1] = tx;
349 return;
350 case 'l': /* left */
351 p[0] = xsiz-1-tx;
352 p[1] = ysiz-1-ty;
353 return;
354 case 'd': /* down */
355 p[0] = ty;
356 p[1] = ysiz-1-tx;
357 return;
358 }
359 }
360
361
362 mapedge(x, y, run, rise) /* map an edge */
363 register int x, y;
364 int run, rise;
365 {
366 int xstep;
367 int rise2, run2;
368 int n;
369
370 if (rise == 0)
371 return;
372 /* always draw up */
373 if (rise < 0) {
374 x += run;
375 y += rise;
376 rise = -rise;
377 run = -run;
378 }
379 if (run < 0) {
380 xstep = -1;
381 run = -run;
382 } else
383 xstep = 1;
384 n = rise;
385 run2 = rise2 = 0;
386 while (n)
387 if (rise2 >= run2) {
388 tglbit(x, y);
389 n--;
390 y++;
391 run2 += run;
392 } else {
393 x += xstep;
394 rise2 += rise;
395 }
396 }
397
398
399 writemap(fp) /* write out bitmap */
400 FILE *fp;
401 {
402 COLR pixval[SSS*SSS+1]; /* possible pixel values */
403 COLOR ctmp0, ctmp1;
404 double d;
405 COLR *scanout;
406 int x, y;
407 register int i, j;
408 int cnt;
409 register int inglyph;
410
411 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
412
413 scanout = (COLR *)malloc(xsiz/SSS*sizeof(COLR));
414 if (scanout == NULL)
415 error(SYSTEM, "Out of memory in writemap");
416 for (i = 0; i <= SSS*SSS; i++) { /* compute possible values */
417 copycolor(ctmp0, fgcolor);
418 d = (double)i/(SSS*SSS);
419 scalecolor(ctmp0, d);
420 copycolor(ctmp1, bgcolor);
421 d = 1.0 - d;
422 scalecolor(ctmp1, d);
423 addcolor(ctmp0, ctmp1);
424 setcolr(pixval[i], colval(ctmp0,RED),
425 colval(ctmp0,GRN), colval(ctmp0,BLU));
426 }
427 for (y = ysiz/SSS-1; y >= 0; y--) {
428 inglyph = 0;
429 for (x = 0; x < xsiz/SSS; x++) {
430 cnt = 0;
431 for (j = 0; j < SSS; j++)
432 for (i = 0; i < SSS; i++) {
433 if (tstbit(x*SSS+i, y*SSS+j))
434 inglyph ^= 1<<j;
435 if (inglyph & 1<<j)
436 cnt++;
437 }
438 copycolr(scanout[x], pixval[cnt]);
439 }
440 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
441 fprintf(stderr, "write error in writemap\n");
442 exit(1);
443 }
444 }
445 free((void *)scanout);
446 }