ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.9
Committed: Tue Jul 7 17:35:42 1992 UTC (31 years, 9 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.8: +36 -6 lines
Log Message:
added -x and -y options to control output size

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 xsiz = xsiz = 0;
121 break;
122 case 'a': /* aspect ratio */
123 aspect = atof(argv[++an]);
124 break;
125 case 's': /* spacing */
126 spacing = atof(argv[++an]);
127 break;
128 default:;
129 unkopt:
130 fprintf(stderr, "%s: unknown option: %s\n",
131 argv[0], argv[an]);
132 exit(1);
133 }
134 /* load font file */
135 if ((libpath = getenv(ULIBVAR)) == NULL)
136 libpath = DEFPATH;
137 ourfont = getfont(fontfile);
138 /* get text */
139 if (an == argc)
140 gettext(stdin);
141 else
142 arg_text(argc-an, argv+an);
143
144 /* create bit map */
145 makemap();
146 /* convert text to bitmap */
147 maptext();
148 /* print header */
149 printargs(argc, argv, stdout);
150 fputformat(COLRFMT, stdout);
151 putchar('\n');
152 /* write out bitmap */
153 writemap(stdout);
154
155 exit(0);
156 }
157
158
159 makemap() /* create the bit map */
160 {
161 double pictaspect;
162
163 if (direct == 'r' || direct == 'l') {
164 if (xsiz == 0 || ysiz == 0) {
165 cwidth = cheight/aspect + 0.5;
166 xsiz = (long)maxwidth*cwidth >> 8;
167 ysiz = nlines*cheight;
168 } else {
169 pictaspect = 256*nlines*aspect/maxwidth;
170 if (pictaspect*xsiz < ysiz)
171 ysiz = pictaspect*xsiz + 0.5;
172 else
173 xsiz = ysiz/pictaspect + 0.5;
174 cheight = ysiz/nlines;
175 cwidth = cheight/aspect + 0.5;
176 }
177 } else { /* reverse orientation */
178 if (xsiz == 0 || ysiz == 0) {
179 cwidth = cheight/aspect + 0.5;
180 xsiz = nlines*cheight;
181 ysiz = (long)maxwidth*cwidth >> 8;
182 } else {
183 pictaspect = maxwidth/(256*nlines*aspect);
184 if (pictaspect*xsiz < ysiz)
185 ysiz = pictaspect*xsiz + 0.5;
186 else
187 xsiz = ysiz/pictaspect + 0.5;
188 cheight = xsiz/nlines;
189 cwidth = cheight/aspect + 0.5;
190 }
191 }
192 if (xsiz % SSS)
193 xsiz += SSS - xsiz%SSS;
194 if (ysiz % SSS)
195 ysiz += SSS - ysiz%SSS;
196 xdim = (xsiz+7)/8;
197 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
198 if (ourbitmap == NULL)
199 error(SYSTEM, "Out of memory in makemap");
200 bzero((char *)ourbitmap, ysiz*xdim);
201 }
202
203
204 gettext(fp) /* get text from a file */
205 FILE *fp;
206 {
207 char *fgets();
208 char buf[MAXLINE];
209 register LINE *curl;
210 int len;
211
212 maxline = 0;
213 maxwidth = 0;
214 nlines = 0;
215 while (fgets(buf, MAXLINE, fp) != NULL) {
216 curl = (LINE *)malloc(sizeof(LINE));
217 if (curl == NULL)
218 goto memerr;
219 len = strlen(buf);
220 curl->s = malloc(len);
221 curl->sp = (short *)malloc(sizeof(short)*len--);
222 if (curl->s == NULL | curl->sp == NULL)
223 goto memerr;
224 if (len > maxline)
225 maxline = len;
226 strncpy(curl->s, buf, len);
227 curl->s[len] = '\0';
228 if (spacing < -1./256.)
229 len = squeeztext(curl->sp, curl->s, ourfont,
230 (int)(spacing*-256.0));
231 else if (spacing > 1./256.)
232 len = proptext(curl->sp, curl->s, ourfont,
233 (int)(spacing*256.0), 3);
234 else
235 len = uniftext(curl->sp, curl->s, ourfont);
236 if (len > maxwidth)
237 maxwidth = len;
238 curl->next = ourtext;
239 ourtext = curl;
240 nlines++;
241 }
242 return;
243 memerr:
244 error(SYSTEM, "Out of memory in gettext");
245 }
246
247
248 arg_text(ac, av) /* get text from arguments */
249 int ac;
250 char *av[];
251 {
252 register char *cp;
253
254 ourtext = (LINE *)malloc(sizeof(LINE));
255 if (ourtext == NULL)
256 goto memerr;
257 ourtext->s = malloc(MAXLINE);
258 if (ourtext->s == NULL)
259 goto memerr;
260 for (cp = ourtext->s; ac-- > 0; av++) {
261 strcpy(cp, *av);
262 cp += strlen(*av);
263 *cp++ = ' ';
264 }
265 *--cp = '\0';
266 ourtext->next = NULL;
267 maxline = strlen(ourtext->s);
268 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
269 if (ourtext->sp == NULL)
270 goto memerr;
271 if (spacing < 0.0)
272 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
273 (int)(spacing*-256.0));
274 else if (spacing > 0.0)
275 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
276 (int)(spacing*256.0), 3);
277 else
278 maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
279 nlines = 1;
280 return;
281 memerr:
282 error(SYSTEM, "Out of memory in arg_text");
283 }
284
285
286 maptext() /* map our text */
287 {
288 register LINE *curl;
289 int l, len;
290 register int i, c;
291
292 for (l = 0, curl = ourtext; curl != NULL; l += 256, curl = curl->next) {
293 len = strlen(curl->s); c = 0;
294 for (i = 0; i < len; i++) {
295 c += curl->sp[i];
296 mapglyph(ourfont->fg[curl->s[i]&0xff], c, l);
297 }
298 }
299 }
300
301
302 mapglyph(gl, tx0, ty0) /* convert a glyph */
303 GLYPH *gl;
304 int tx0, ty0;
305 {
306 int n;
307 register GORD *gp;
308 int p0[2], p1[2];
309
310 if (gl == NULL)
311 return;
312
313 n = gl->nverts;
314 gp = gvlist(gl);
315 mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
316 while (n--) {
317 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
318 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
319 p0[0] = p1[0]; p0[1] = p1[1];
320 gp += 2;
321 }
322 }
323
324
325 mapcoord(p, tx, ty) /* map text to picture coordinates */
326 int p[2], tx, ty;
327 {
328 tx = (long)tx*cwidth >> 8;
329 ty = (long)ty*cheight >> 8;
330
331 switch (direct) {
332 case 'r': /* right */
333 p[0] = tx;
334 p[1] = ty;
335 return;
336 case 'u': /* up */
337 p[0] = xsiz-1-ty;
338 p[1] = tx;
339 return;
340 case 'l': /* left */
341 p[0] = xsiz-1-tx;
342 p[1] = ysiz-1-ty;
343 return;
344 case 'd': /* down */
345 p[0] = ty;
346 p[1] = ysiz-1-tx;
347 return;
348 }
349 }
350
351
352 mapedge(x, y, run, rise) /* map an edge */
353 register int x, y;
354 int run, rise;
355 {
356 int xstep;
357 int rise2, run2;
358 int n;
359
360 if (rise == 0)
361 return;
362 /* always draw up */
363 if (rise < 0) {
364 x += run;
365 y += rise;
366 rise = -rise;
367 run = -run;
368 }
369 if (run < 0) {
370 xstep = -1;
371 run = -run;
372 } else
373 xstep = 1;
374 n = rise;
375 run2 = rise2 = 0;
376 while (n)
377 if (rise2 >= run2) {
378 tglbit(x, y);
379 n--;
380 y++;
381 run2 += run;
382 } else {
383 x += xstep;
384 rise2 += rise;
385 }
386 }
387
388
389 writemap(fp) /* write out bitmap */
390 FILE *fp;
391 {
392 COLR pixval[SSS*SSS+1]; /* possible pixel values */
393 COLOR ctmp0, ctmp1;
394 double d;
395 COLR *scanout;
396 int x, y;
397 register int i, j;
398 int cnt;
399 register int inglyph;
400
401 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
402
403 scanout = (COLR *)malloc(xsiz/SSS*sizeof(COLR));
404 if (scanout == NULL)
405 error(SYSTEM, "Out of memory in writemap");
406 for (i = 0; i <= SSS*SSS; i++) { /* compute possible values */
407 copycolor(ctmp0, fgcolor);
408 d = (double)i/(SSS*SSS);
409 scalecolor(ctmp0, d);
410 copycolor(ctmp1, bgcolor);
411 d = 1.0 - d;
412 scalecolor(ctmp1, d);
413 addcolor(ctmp0, ctmp1);
414 setcolr(pixval[i], colval(ctmp0,RED),
415 colval(ctmp0,GRN), colval(ctmp0,BLU));
416 }
417 for (y = ysiz/SSS-1; y >= 0; y--) {
418 inglyph = 0;
419 for (x = 0; x < xsiz/SSS; x++) {
420 cnt = 0;
421 for (j = 0; j < SSS; j++)
422 for (i = 0; i < SSS; i++) {
423 if (tstbit(x*SSS+i, y*SSS+j))
424 inglyph ^= 1<<j;
425 if (inglyph & 1<<j)
426 cnt++;
427 }
428 copycolr(scanout[x], pixval[cnt]);
429 }
430 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
431 fprintf(stderr, "write error in writemap\n");
432 exit(1);
433 }
434 }
435 free((char *)scanout);
436 }