ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.20
Committed: Sun Jun 8 12:03:10 2003 UTC (20 years, 10 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.19: +2 -1 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.20 static const char RCSid[] = "$Id: psign.c,v 2.19 2003/06/05 19:29:34 schorsch 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 schorsch 2.20 #include "platform.h"
12 greg 1.1 #include "color.h"
13 greg 2.3 #include "font.h"
14    
15 greg 2.13 #ifndef SSS
16     #define SSS 3 /* super-sample size */
17 greg 2.5 #endif
18 greg 2.4
19 greg 2.13 #define MAXLINE 512 /* longest allowable line */
20 greg 1.1
21 greg 1.2 char *fontfile = "helvet.fnt"; /* our font file */
22 greg 1.1
23 greg 2.5 COLOR bgcolor = WHTCOLOR; /* background color */
24     COLOR fgcolor = BLKCOLOR; /* foreground color */
25 greg 1.1
26     int direct = 'r'; /* direction (right, up, left, down) */
27    
28 greg 2.5 int cheight = 32*SSS; /* character height */
29 greg 2.13 double aspect = 1.67; /* height/width character aspect */
30     double spacing = 0.0; /* character spacing */
31 greg 1.1 int cwidth; /* computed character width */
32    
33     unsigned char *ourbitmap; /* our output bitmap */
34     int xsiz, ysiz; /* bitmap dimensions */
35     int xdim; /* size of horizontal scan (bytes) */
36    
37 greg 2.13 #define bitop(x,y,op) (ourbitmap[(y)*xdim+((x)>>3)] op (1<<((x)&7)))
38     #define tstbit(x,y) bitop(x,y,&)
39     #define setbit(x,y) bitop(x,y,|=)
40     #define clrbit(x,y) bitop(x,y,&=~)
41     #define tglbit(x,y) bitop(x,y,^=)
42 greg 1.1
43 greg 2.3 FONT *ourfont; /* our font */
44 greg 1.1
45     typedef struct line {
46     char *s; /* line w/o LF */
47 greg 2.4 short *sp; /* character spacing */
48 greg 1.1 struct line *next; /* next line up */
49     } LINE;
50    
51     LINE *ourtext; /* our text */
52     int nlines, maxline; /* text dimensions */
53 greg 2.4 int maxwidth; /* maximum line width (dvi) */
54 greg 1.1
55    
56     main(argc, argv)
57     int argc;
58     char *argv[];
59     {
60     int an;
61 schorsch 2.19 SET_FILE_BINARY(stdout);
62 greg 1.1 for (an = 1; an < argc && argv[an][0] == '-'; an++)
63     switch (argv[an][1]) {
64     case 'c': /* color */
65     switch (argv[an][2]) {
66     case 'f': /* foreground */
67 greg 2.5 setcolor(fgcolor, atof(argv[an+1]),
68 greg 1.1 atof(argv[an+2]),
69     atof(argv[an+3]));
70     an += 3;
71     break;
72     case 'b': /* background */
73 greg 2.5 setcolor(bgcolor, atof(argv[an+1]),
74 greg 1.1 atof(argv[an+2]),
75     atof(argv[an+3]));
76     an += 3;
77     break;
78     default:
79     goto unkopt;
80     }
81     break;
82     case 'f': /* font */
83     fontfile = argv[++an];
84     break;
85     case 'd': /* direction */
86     switch (argv[an][2]) {
87     case 'r': /* right */
88     case 'u': /* up */
89     case 'l': /* left */
90     case 'd': /* down */
91     direct = argv[an][2];
92     break;
93     default:
94     goto unkopt;
95     }
96     break;
97 greg 2.9 case 'x': /* x resolution */
98     xsiz = atoi(argv[++an])*SSS;
99     break;
100     case 'y':
101     ysiz = atoi(argv[++an])*SSS;
102     break;
103 greg 1.1 case 'h': /* height of characters */
104 greg 2.5 cheight = atoi(argv[++an])*SSS;
105 greg 1.1 break;
106     case 'a': /* aspect ratio */
107     aspect = atof(argv[++an]);
108     break;
109 greg 2.6 case 's': /* spacing */
110     spacing = atof(argv[++an]);
111     break;
112 greg 1.1 default:;
113     unkopt:
114     fprintf(stderr, "%s: unknown option: %s\n",
115     argv[0], argv[an]);
116     exit(1);
117     }
118 greg 2.4 /* load font file */
119     ourfont = getfont(fontfile);
120 greg 1.1 /* get text */
121     if (an == argc)
122     gettext(stdin);
123     else
124     arg_text(argc-an, argv+an);
125    
126     /* create bit map */
127     makemap();
128     /* convert text to bitmap */
129     maptext();
130     /* print header */
131 greg 2.16 newheader("RADIANCE", stdout);
132 greg 1.1 printargs(argc, argv, stdout);
133 greg 1.3 fputformat(COLRFMT, stdout);
134     putchar('\n');
135 greg 1.1 /* write out bitmap */
136     writemap(stdout);
137    
138     exit(0);
139     }
140    
141    
142     makemap() /* create the bit map */
143     {
144 greg 2.13 double pictaspect;
145 greg 2.9
146 greg 1.1 if (direct == 'r' || direct == 'l') {
147 greg 2.11 if (xsiz <= 0) {
148 greg 2.9 cwidth = cheight/aspect + 0.5;
149     xsiz = (long)maxwidth*cwidth >> 8;
150     ysiz = nlines*cheight;
151 greg 2.10 } else if (aspect > FTINY) {
152 greg 2.11 if (ysiz <= 0)
153     ysiz = cheight*nlines;
154 greg 2.9 pictaspect = 256*nlines*aspect/maxwidth;
155     if (pictaspect*xsiz < ysiz)
156     ysiz = pictaspect*xsiz + 0.5;
157     else
158     xsiz = ysiz/pictaspect + 0.5;
159     cheight = ysiz/nlines;
160 greg 2.14 cwidth = cheight/aspect;
161 greg 2.10 } else {
162 greg 2.11 if (ysiz <= 0)
163     ysiz = cheight*nlines;
164 greg 2.10 pictaspect = (double)ysiz/xsiz;
165     aspect = pictaspect*maxwidth/(256*nlines);
166     cheight = ysiz/nlines;
167 greg 2.14 cwidth = cheight/aspect;
168 greg 2.9 }
169 greg 1.1 } else { /* reverse orientation */
170 greg 2.11 if (ysiz <= 0) {
171 greg 2.9 cwidth = cheight/aspect + 0.5;
172     xsiz = nlines*cheight;
173     ysiz = (long)maxwidth*cwidth >> 8;
174 greg 2.10 } else if (aspect > FTINY) {
175 greg 2.11 if (xsiz <= 0)
176     xsiz = cheight*nlines;
177 greg 2.9 pictaspect = maxwidth/(256*nlines*aspect);
178     if (pictaspect*xsiz < ysiz)
179     ysiz = pictaspect*xsiz + 0.5;
180     else
181     xsiz = ysiz/pictaspect + 0.5;
182 greg 2.10 cheight = xsiz/nlines;
183 greg 2.14 cwidth = cheight/aspect;
184 greg 2.10 } else {
185 greg 2.11 if (xsiz <= 0)
186     xsiz = cheight*nlines;
187 greg 2.10 pictaspect = (double)ysiz/xsiz;
188     aspect = maxwidth/(256*nlines*pictaspect);
189 greg 2.9 cheight = xsiz/nlines;
190 greg 2.14 cwidth = cheight/aspect;
191 greg 2.9 }
192 greg 1.1 }
193 greg 2.5 if (xsiz % SSS)
194     xsiz += SSS - xsiz%SSS;
195     if (ysiz % SSS)
196     ysiz += SSS - ysiz%SSS;
197 greg 1.1 xdim = (xsiz+7)/8;
198 greg 2.8 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
199 greg 2.5 if (ourbitmap == NULL)
200     error(SYSTEM, "Out of memory in makemap");
201 greg 2.8 bzero((char *)ourbitmap, ysiz*xdim);
202 greg 1.1 }
203    
204    
205     gettext(fp) /* get text from a file */
206     FILE *fp;
207     {
208     char buf[MAXLINE];
209     register LINE *curl;
210     int len;
211    
212     maxline = 0;
213 greg 2.4 maxwidth = 0;
214 greg 1.1 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 greg 2.18 curl->s = (char *)malloc(len);
221 greg 2.4 curl->sp = (short *)malloc(sizeof(short)*len--);
222     if (curl->s == NULL | curl->sp == NULL)
223 greg 1.1 goto memerr;
224 greg 2.4 if (len > maxline)
225     maxline = len;
226 greg 1.1 strncpy(curl->s, buf, len);
227     curl->s[len] = '\0';
228 greg 2.7 if (spacing < -1./256.)
229 greg 2.6 len = squeeztext(curl->sp, curl->s, ourfont,
230 greg 2.14 (int)(spacing*-256.));
231 greg 2.7 else if (spacing > 1./256.)
232 greg 2.6 len = proptext(curl->sp, curl->s, ourfont,
233 greg 2.14 (int)(spacing*256.), 3);
234 greg 2.6 else
235     len = uniftext(curl->sp, curl->s, ourfont);
236 greg 2.4 if (len > maxwidth)
237     maxwidth = len;
238 greg 1.1 curl->next = ourtext;
239     ourtext = curl;
240     nlines++;
241     }
242     return;
243     memerr:
244 greg 2.5 error(SYSTEM, "Out of memory in gettext");
245 greg 1.1 }
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 greg 2.18 ourtext->s = (char *)malloc(MAXLINE);
258 greg 1.1 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 greg 2.4 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
269     if (ourtext->sp == NULL)
270     goto memerr;
271 greg 2.14 if (spacing < -1./256.)
272 greg 2.6 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
273 greg 2.14 (int)(spacing*-256.));
274     else if (spacing > 1./256.)
275 greg 2.6 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
276 greg 2.14 (int)(spacing*256.), 3);
277 greg 2.6 else
278     maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
279 greg 1.1 nlines = 1;
280     return;
281     memerr:
282 greg 2.5 error(SYSTEM, "Out of memory in arg_text");
283 greg 1.1 }
284    
285    
286     maptext() /* map our text */
287     {
288     register LINE *curl;
289 greg 2.4 int l, len;
290     register int i, c;
291 greg 1.1
292 greg 2.4 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 greg 1.1 }
300    
301    
302     mapglyph(gl, tx0, ty0) /* convert a glyph */
303 greg 2.3 GLYPH *gl;
304 greg 1.1 int tx0, ty0;
305     {
306     int n;
307 greg 2.3 register GORD *gp;
308 greg 1.1 int p0[2], p1[2];
309    
310     if (gl == NULL)
311     return;
312    
313 greg 2.3 n = gl->nverts;
314     gp = gvlist(gl);
315     mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
316 greg 1.1 while (n--) {
317 greg 2.3 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
318 greg 1.1 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
319     p0[0] = p1[0]; p0[1] = p1[1];
320 greg 2.3 gp += 2;
321 greg 1.1 }
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 greg 2.5 COLR pixval[SSS*SSS+1]; /* possible pixel values */
393     COLOR ctmp0, ctmp1;
394 greg 2.13 double d;
395 greg 1.1 COLR *scanout;
396 greg 2.5 int x, y;
397     register int i, j;
398     int cnt;
399 greg 1.1 register int inglyph;
400    
401 greg 2.5 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
402 greg 1.1
403 greg 2.5 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 greg 1.1 }
417 greg 2.5 for (y = ysiz/SSS-1; y >= 0; y--) {
418 greg 1.1 inglyph = 0;
419 greg 2.5 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 greg 1.1 }
430 greg 2.5 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
431 greg 1.1 fprintf(stderr, "write error in writemap\n");
432     exit(1);
433     }
434     }
435 greg 2.18 free((void *)scanout);
436 greg 1.1 }