ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.11
Committed: Wed Jul 8 13:58:10 1992 UTC (31 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +10 -3 lines
Log Message:
made it so just one of -x or -y can be given along with -h

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