ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.17
Committed: Thu Apr 14 04:53:54 1994 UTC (30 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.16: +0 -6 lines
Log Message:
changed libpath to getlibpath()

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