ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.18
Committed: Sat Feb 22 02:07:27 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.17: +4 -7 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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