ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.15
Committed: Fri Jun 4 17:02:48 1993 UTC (30 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.14: +0 -1 lines
Log Message:
removed declaration of fgets()

File Contents

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