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, 11 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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.19 static const char RCSid[] = "$Id: psign.c,v 2.18 2003/02/22 02:07:27 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * psign.c - produce picture from text.
6     *
7     * 7/1/87
8     */
9    
10 greg 2.3 #include "standard.h"
11 greg 1.1 #include "color.h"
12 greg 2.3 #include "font.h"
13    
14 greg 2.13 #ifndef SSS
15     #define SSS 3 /* super-sample size */
16 greg 2.5 #endif
17 greg 2.4
18 greg 2.13 #define MAXLINE 512 /* longest allowable line */
19 greg 1.1
20 greg 1.2 char *fontfile = "helvet.fnt"; /* our font file */
21 greg 1.1
22 greg 2.5 COLOR bgcolor = WHTCOLOR; /* background color */
23     COLOR fgcolor = BLKCOLOR; /* foreground color */
24 greg 1.1
25     int direct = 'r'; /* direction (right, up, left, down) */
26    
27 greg 2.5 int cheight = 32*SSS; /* character height */
28 greg 2.13 double aspect = 1.67; /* height/width character aspect */
29     double spacing = 0.0; /* character spacing */
30 greg 1.1 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 greg 2.13 #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 greg 1.1
42 greg 2.3 FONT *ourfont; /* our font */
43 greg 1.1
44     typedef struct line {
45     char *s; /* line w/o LF */
46 greg 2.4 short *sp; /* character spacing */
47 greg 1.1 struct line *next; /* next line up */
48     } LINE;
49    
50     LINE *ourtext; /* our text */
51     int nlines, maxline; /* text dimensions */
52 greg 2.4 int maxwidth; /* maximum line width (dvi) */
53 greg 1.1
54    
55     main(argc, argv)
56     int argc;
57     char *argv[];
58     {
59     int an;
60 schorsch 2.19 SET_FILE_BINARY(stdout);
61 greg 1.1 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 greg 2.5 setcolor(fgcolor, atof(argv[an+1]),
67 greg 1.1 atof(argv[an+2]),
68     atof(argv[an+3]));
69     an += 3;
70     break;
71     case 'b': /* background */
72 greg 2.5 setcolor(bgcolor, atof(argv[an+1]),
73 greg 1.1 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 greg 2.9 case 'x': /* x resolution */
97     xsiz = atoi(argv[++an])*SSS;
98     break;
99     case 'y':
100     ysiz = atoi(argv[++an])*SSS;
101     break;
102 greg 1.1 case 'h': /* height of characters */
103 greg 2.5 cheight = atoi(argv[++an])*SSS;
104 greg 1.1 break;
105     case 'a': /* aspect ratio */
106     aspect = atof(argv[++an]);
107     break;
108 greg 2.6 case 's': /* spacing */
109     spacing = atof(argv[++an]);
110     break;
111 greg 1.1 default:;
112     unkopt:
113     fprintf(stderr, "%s: unknown option: %s\n",
114     argv[0], argv[an]);
115     exit(1);
116     }
117 greg 2.4 /* load font file */
118     ourfont = getfont(fontfile);
119 greg 1.1 /* 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 greg 2.16 newheader("RADIANCE", stdout);
131 greg 1.1 printargs(argc, argv, stdout);
132 greg 1.3 fputformat(COLRFMT, stdout);
133     putchar('\n');
134 greg 1.1 /* write out bitmap */
135     writemap(stdout);
136    
137     exit(0);
138     }
139    
140    
141     makemap() /* create the bit map */
142     {
143 greg 2.13 double pictaspect;
144 greg 2.9
145 greg 1.1 if (direct == 'r' || direct == 'l') {
146 greg 2.11 if (xsiz <= 0) {
147 greg 2.9 cwidth = cheight/aspect + 0.5;
148     xsiz = (long)maxwidth*cwidth >> 8;
149     ysiz = nlines*cheight;
150 greg 2.10 } else if (aspect > FTINY) {
151 greg 2.11 if (ysiz <= 0)
152     ysiz = cheight*nlines;
153 greg 2.9 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 greg 2.14 cwidth = cheight/aspect;
160 greg 2.10 } else {
161 greg 2.11 if (ysiz <= 0)
162     ysiz = cheight*nlines;
163 greg 2.10 pictaspect = (double)ysiz/xsiz;
164     aspect = pictaspect*maxwidth/(256*nlines);
165     cheight = ysiz/nlines;
166 greg 2.14 cwidth = cheight/aspect;
167 greg 2.9 }
168 greg 1.1 } else { /* reverse orientation */
169 greg 2.11 if (ysiz <= 0) {
170 greg 2.9 cwidth = cheight/aspect + 0.5;
171     xsiz = nlines*cheight;
172     ysiz = (long)maxwidth*cwidth >> 8;
173 greg 2.10 } else if (aspect > FTINY) {
174 greg 2.11 if (xsiz <= 0)
175     xsiz = cheight*nlines;
176 greg 2.9 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 greg 2.10 cheight = xsiz/nlines;
182 greg 2.14 cwidth = cheight/aspect;
183 greg 2.10 } else {
184 greg 2.11 if (xsiz <= 0)
185     xsiz = cheight*nlines;
186 greg 2.10 pictaspect = (double)ysiz/xsiz;
187     aspect = maxwidth/(256*nlines*pictaspect);
188 greg 2.9 cheight = xsiz/nlines;
189 greg 2.14 cwidth = cheight/aspect;
190 greg 2.9 }
191 greg 1.1 }
192 greg 2.5 if (xsiz % SSS)
193     xsiz += SSS - xsiz%SSS;
194     if (ysiz % SSS)
195     ysiz += SSS - ysiz%SSS;
196 greg 1.1 xdim = (xsiz+7)/8;
197 greg 2.8 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
198 greg 2.5 if (ourbitmap == NULL)
199     error(SYSTEM, "Out of memory in makemap");
200 greg 2.8 bzero((char *)ourbitmap, ysiz*xdim);
201 greg 1.1 }
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 greg 2.4 maxwidth = 0;
213 greg 1.1 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 greg 2.18 curl->s = (char *)malloc(len);
220 greg 2.4 curl->sp = (short *)malloc(sizeof(short)*len--);
221     if (curl->s == NULL | curl->sp == NULL)
222 greg 1.1 goto memerr;
223 greg 2.4 if (len > maxline)
224     maxline = len;
225 greg 1.1 strncpy(curl->s, buf, len);
226     curl->s[len] = '\0';
227 greg 2.7 if (spacing < -1./256.)
228 greg 2.6 len = squeeztext(curl->sp, curl->s, ourfont,
229 greg 2.14 (int)(spacing*-256.));
230 greg 2.7 else if (spacing > 1./256.)
231 greg 2.6 len = proptext(curl->sp, curl->s, ourfont,
232 greg 2.14 (int)(spacing*256.), 3);
233 greg 2.6 else
234     len = uniftext(curl->sp, curl->s, ourfont);
235 greg 2.4 if (len > maxwidth)
236     maxwidth = len;
237 greg 1.1 curl->next = ourtext;
238     ourtext = curl;
239     nlines++;
240     }
241     return;
242     memerr:
243 greg 2.5 error(SYSTEM, "Out of memory in gettext");
244 greg 1.1 }
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 greg 2.18 ourtext->s = (char *)malloc(MAXLINE);
257 greg 1.1 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 greg 2.4 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
268     if (ourtext->sp == NULL)
269     goto memerr;
270 greg 2.14 if (spacing < -1./256.)
271 greg 2.6 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
272 greg 2.14 (int)(spacing*-256.));
273     else if (spacing > 1./256.)
274 greg 2.6 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
275 greg 2.14 (int)(spacing*256.), 3);
276 greg 2.6 else
277     maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
278 greg 1.1 nlines = 1;
279     return;
280     memerr:
281 greg 2.5 error(SYSTEM, "Out of memory in arg_text");
282 greg 1.1 }
283    
284    
285     maptext() /* map our text */
286     {
287     register LINE *curl;
288 greg 2.4 int l, len;
289     register int i, c;
290 greg 1.1
291 greg 2.4 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 greg 1.1 }
299    
300    
301     mapglyph(gl, tx0, ty0) /* convert a glyph */
302 greg 2.3 GLYPH *gl;
303 greg 1.1 int tx0, ty0;
304     {
305     int n;
306 greg 2.3 register GORD *gp;
307 greg 1.1 int p0[2], p1[2];
308    
309     if (gl == NULL)
310     return;
311    
312 greg 2.3 n = gl->nverts;
313     gp = gvlist(gl);
314     mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
315 greg 1.1 while (n--) {
316 greg 2.3 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
317 greg 1.1 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
318     p0[0] = p1[0]; p0[1] = p1[1];
319 greg 2.3 gp += 2;
320 greg 1.1 }
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 greg 2.5 COLR pixval[SSS*SSS+1]; /* possible pixel values */
392     COLOR ctmp0, ctmp1;
393 greg 2.13 double d;
394 greg 1.1 COLR *scanout;
395 greg 2.5 int x, y;
396     register int i, j;
397     int cnt;
398 greg 1.1 register int inglyph;
399    
400 greg 2.5 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
401 greg 1.1
402 greg 2.5 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 greg 1.1 }
416 greg 2.5 for (y = ysiz/SSS-1; y >= 0; y--) {
417 greg 1.1 inglyph = 0;
418 greg 2.5 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 greg 1.1 }
429 greg 2.5 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
430 greg 1.1 fprintf(stderr, "write error in writemap\n");
431     exit(1);
432     }
433     }
434 greg 2.18 free((void *)scanout);
435 greg 1.1 }