ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.19
Committed: Thu Jun 5 19:29:34 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.18: +2 -6 lines
Log Message:
Macros for setting binary file mode. Replacing MSDOS by _WIN32.

File Contents

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