ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.12
Committed: Tue Sep 8 10:35:08 1992 UTC (31 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.11: +2 -9 lines
Log Message:
portability fixes

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
70 for (an = 1; an < argc && argv[an][0] == '-'; an++)
71 switch (argv[an][1]) {
72 case 'c': /* color */
73 switch (argv[an][2]) {
74 case 'f': /* foreground */
75 setcolor(fgcolor, atof(argv[an+1]),
76 atof(argv[an+2]),
77 atof(argv[an+3]));
78 an += 3;
79 break;
80 case 'b': /* background */
81 setcolor(bgcolor, atof(argv[an+1]),
82 atof(argv[an+2]),
83 atof(argv[an+3]));
84 an += 3;
85 break;
86 default:
87 goto unkopt;
88 }
89 break;
90 case 'f': /* font */
91 fontfile = argv[++an];
92 break;
93 case 'd': /* direction */
94 switch (argv[an][2]) {
95 case 'r': /* right */
96 case 'u': /* up */
97 case 'l': /* left */
98 case 'd': /* down */
99 direct = argv[an][2];
100 break;
101 default:
102 goto unkopt;
103 }
104 break;
105 case 'x': /* x resolution */
106 xsiz = atoi(argv[++an])*SSS;
107 break;
108 case 'y':
109 ysiz = atoi(argv[++an])*SSS;
110 break;
111 case 'h': /* height of characters */
112 cheight = atoi(argv[++an])*SSS;
113 break;
114 case 'a': /* aspect ratio */
115 aspect = atof(argv[++an]);
116 break;
117 case 's': /* spacing */
118 spacing = atof(argv[++an]);
119 break;
120 default:;
121 unkopt:
122 fprintf(stderr, "%s: unknown option: %s\n",
123 argv[0], argv[an]);
124 exit(1);
125 }
126 /* load font file */
127 if ((libpath = getenv(ULIBVAR)) == NULL)
128 libpath = DEFPATH;
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 printargs(argc, argv, stdout);
142 fputformat(COLRFMT, stdout);
143 putchar('\n');
144 /* write out bitmap */
145 writemap(stdout);
146
147 exit(0);
148 }
149
150
151 makemap() /* create the bit map */
152 {
153 double pictaspect;
154
155 if (direct == 'r' || direct == 'l') {
156 if (xsiz <= 0) {
157 cwidth = cheight/aspect + 0.5;
158 xsiz = (long)maxwidth*cwidth >> 8;
159 ysiz = nlines*cheight;
160 } else if (aspect > FTINY) {
161 if (ysiz <= 0)
162 ysiz = cheight*nlines;
163 pictaspect = 256*nlines*aspect/maxwidth;
164 if (pictaspect*xsiz < ysiz)
165 ysiz = pictaspect*xsiz + 0.5;
166 else
167 xsiz = ysiz/pictaspect + 0.5;
168 cheight = ysiz/nlines;
169 cwidth = cheight/aspect + 0.5;
170 } else {
171 if (ysiz <= 0)
172 ysiz = cheight*nlines;
173 pictaspect = (double)ysiz/xsiz;
174 aspect = pictaspect*maxwidth/(256*nlines);
175 cheight = ysiz/nlines;
176 cwidth = cheight/aspect + 0.5;
177 }
178 } else { /* reverse orientation */
179 if (ysiz <= 0) {
180 cwidth = cheight/aspect + 0.5;
181 xsiz = nlines*cheight;
182 ysiz = (long)maxwidth*cwidth >> 8;
183 } else if (aspect > FTINY) {
184 if (xsiz <= 0)
185 xsiz = cheight*nlines;
186 pictaspect = maxwidth/(256*nlines*aspect);
187 if (pictaspect*xsiz < ysiz)
188 ysiz = pictaspect*xsiz + 0.5;
189 else
190 xsiz = ysiz/pictaspect + 0.5;
191 cheight = xsiz/nlines;
192 cwidth = cheight/aspect + 0.5;
193 } else {
194 if (xsiz <= 0)
195 xsiz = cheight*nlines;
196 pictaspect = (double)ysiz/xsiz;
197 aspect = maxwidth/(256*nlines*pictaspect);
198 cheight = xsiz/nlines;
199 cwidth = cheight/aspect + 0.5;
200 }
201 }
202 if (xsiz % SSS)
203 xsiz += SSS - xsiz%SSS;
204 if (ysiz % SSS)
205 ysiz += SSS - ysiz%SSS;
206 xdim = (xsiz+7)/8;
207 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
208 if (ourbitmap == NULL)
209 error(SYSTEM, "Out of memory in makemap");
210 bzero((char *)ourbitmap, ysiz*xdim);
211 }
212
213
214 gettext(fp) /* get text from a file */
215 FILE *fp;
216 {
217 char *fgets();
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 = 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.0));
241 else if (spacing > 1./256.)
242 len = proptext(curl->sp, curl->s, ourfont,
243 (int)(spacing*256.0), 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 = 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 < 0.0)
282 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
283 (int)(spacing*-256.0));
284 else if (spacing > 0.0)
285 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
286 (int)(spacing*256.0), 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((char *)scanout);
446 }