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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.18 static const char RCSid[] = "$Id$";
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
12     #include "color.h"
13    
14 greg 2.3 #include "font.h"
15    
16 greg 2.13 #ifndef SSS
17     #define SSS 3 /* super-sample size */
18 greg 2.5 #endif
19 greg 2.4
20 greg 2.13 #define MAXLINE 512 /* longest allowable line */
21 greg 1.1
22 greg 1.2 char *fontfile = "helvet.fnt"; /* our font file */
23 greg 1.1
24 greg 2.5 COLOR bgcolor = WHTCOLOR; /* background color */
25     COLOR fgcolor = BLKCOLOR; /* foreground color */
26 greg 1.1
27     int direct = 'r'; /* direction (right, up, left, down) */
28    
29 greg 2.5 int cheight = 32*SSS; /* character height */
30 greg 2.13 double aspect = 1.67; /* height/width character aspect */
31     double spacing = 0.0; /* character spacing */
32 greg 1.1 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 greg 2.13 #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 greg 1.1
44 greg 2.3 FONT *ourfont; /* our font */
45 greg 1.1
46     typedef struct line {
47     char *s; /* line w/o LF */
48 greg 2.4 short *sp; /* character spacing */
49 greg 1.1 struct line *next; /* next line up */
50     } LINE;
51    
52     LINE *ourtext; /* our text */
53     int nlines, maxline; /* text dimensions */
54 greg 2.4 int maxwidth; /* maximum line width (dvi) */
55 greg 1.1
56    
57     main(argc, argv)
58     int argc;
59     char *argv[];
60     {
61     int an;
62 greg 2.13 #ifdef MSDOS
63     setmode(fileno(stdout), O_BINARY);
64     #endif
65 greg 1.1 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 greg 2.5 setcolor(fgcolor, atof(argv[an+1]),
71 greg 1.1 atof(argv[an+2]),
72     atof(argv[an+3]));
73     an += 3;
74     break;
75     case 'b': /* background */
76 greg 2.5 setcolor(bgcolor, atof(argv[an+1]),
77 greg 1.1 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 greg 2.9 case 'x': /* x resolution */
101     xsiz = atoi(argv[++an])*SSS;
102     break;
103     case 'y':
104     ysiz = atoi(argv[++an])*SSS;
105     break;
106 greg 1.1 case 'h': /* height of characters */
107 greg 2.5 cheight = atoi(argv[++an])*SSS;
108 greg 1.1 break;
109     case 'a': /* aspect ratio */
110     aspect = atof(argv[++an]);
111     break;
112 greg 2.6 case 's': /* spacing */
113     spacing = atof(argv[++an]);
114     break;
115 greg 1.1 default:;
116     unkopt:
117     fprintf(stderr, "%s: unknown option: %s\n",
118     argv[0], argv[an]);
119     exit(1);
120     }
121 greg 2.4 /* load font file */
122     ourfont = getfont(fontfile);
123 greg 1.1 /* 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 greg 2.16 newheader("RADIANCE", stdout);
135 greg 1.1 printargs(argc, argv, stdout);
136 greg 1.3 fputformat(COLRFMT, stdout);
137     putchar('\n');
138 greg 1.1 /* write out bitmap */
139     writemap(stdout);
140    
141     exit(0);
142     }
143    
144    
145     makemap() /* create the bit map */
146     {
147 greg 2.13 double pictaspect;
148 greg 2.9
149 greg 1.1 if (direct == 'r' || direct == 'l') {
150 greg 2.11 if (xsiz <= 0) {
151 greg 2.9 cwidth = cheight/aspect + 0.5;
152     xsiz = (long)maxwidth*cwidth >> 8;
153     ysiz = nlines*cheight;
154 greg 2.10 } else if (aspect > FTINY) {
155 greg 2.11 if (ysiz <= 0)
156     ysiz = cheight*nlines;
157 greg 2.9 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 greg 2.14 cwidth = cheight/aspect;
164 greg 2.10 } else {
165 greg 2.11 if (ysiz <= 0)
166     ysiz = cheight*nlines;
167 greg 2.10 pictaspect = (double)ysiz/xsiz;
168     aspect = pictaspect*maxwidth/(256*nlines);
169     cheight = ysiz/nlines;
170 greg 2.14 cwidth = cheight/aspect;
171 greg 2.9 }
172 greg 1.1 } else { /* reverse orientation */
173 greg 2.11 if (ysiz <= 0) {
174 greg 2.9 cwidth = cheight/aspect + 0.5;
175     xsiz = nlines*cheight;
176     ysiz = (long)maxwidth*cwidth >> 8;
177 greg 2.10 } else if (aspect > FTINY) {
178 greg 2.11 if (xsiz <= 0)
179     xsiz = cheight*nlines;
180 greg 2.9 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 greg 2.10 cheight = xsiz/nlines;
186 greg 2.14 cwidth = cheight/aspect;
187 greg 2.10 } else {
188 greg 2.11 if (xsiz <= 0)
189     xsiz = cheight*nlines;
190 greg 2.10 pictaspect = (double)ysiz/xsiz;
191     aspect = maxwidth/(256*nlines*pictaspect);
192 greg 2.9 cheight = xsiz/nlines;
193 greg 2.14 cwidth = cheight/aspect;
194 greg 2.9 }
195 greg 1.1 }
196 greg 2.5 if (xsiz % SSS)
197     xsiz += SSS - xsiz%SSS;
198     if (ysiz % SSS)
199     ysiz += SSS - ysiz%SSS;
200 greg 1.1 xdim = (xsiz+7)/8;
201 greg 2.8 ourbitmap = (BYTE *)bmalloc(ysiz*xdim);
202 greg 2.5 if (ourbitmap == NULL)
203     error(SYSTEM, "Out of memory in makemap");
204 greg 2.8 bzero((char *)ourbitmap, ysiz*xdim);
205 greg 1.1 }
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 greg 2.4 maxwidth = 0;
217 greg 1.1 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 greg 2.18 curl->s = (char *)malloc(len);
224 greg 2.4 curl->sp = (short *)malloc(sizeof(short)*len--);
225     if (curl->s == NULL | curl->sp == NULL)
226 greg 1.1 goto memerr;
227 greg 2.4 if (len > maxline)
228     maxline = len;
229 greg 1.1 strncpy(curl->s, buf, len);
230     curl->s[len] = '\0';
231 greg 2.7 if (spacing < -1./256.)
232 greg 2.6 len = squeeztext(curl->sp, curl->s, ourfont,
233 greg 2.14 (int)(spacing*-256.));
234 greg 2.7 else if (spacing > 1./256.)
235 greg 2.6 len = proptext(curl->sp, curl->s, ourfont,
236 greg 2.14 (int)(spacing*256.), 3);
237 greg 2.6 else
238     len = uniftext(curl->sp, curl->s, ourfont);
239 greg 2.4 if (len > maxwidth)
240     maxwidth = len;
241 greg 1.1 curl->next = ourtext;
242     ourtext = curl;
243     nlines++;
244     }
245     return;
246     memerr:
247 greg 2.5 error(SYSTEM, "Out of memory in gettext");
248 greg 1.1 }
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 greg 2.18 ourtext->s = (char *)malloc(MAXLINE);
261 greg 1.1 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 greg 2.4 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
272     if (ourtext->sp == NULL)
273     goto memerr;
274 greg 2.14 if (spacing < -1./256.)
275 greg 2.6 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
276 greg 2.14 (int)(spacing*-256.));
277     else if (spacing > 1./256.)
278 greg 2.6 maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
279 greg 2.14 (int)(spacing*256.), 3);
280 greg 2.6 else
281     maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
282 greg 1.1 nlines = 1;
283     return;
284     memerr:
285 greg 2.5 error(SYSTEM, "Out of memory in arg_text");
286 greg 1.1 }
287    
288    
289     maptext() /* map our text */
290     {
291     register LINE *curl;
292 greg 2.4 int l, len;
293     register int i, c;
294 greg 1.1
295 greg 2.4 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 greg 1.1 }
303    
304    
305     mapglyph(gl, tx0, ty0) /* convert a glyph */
306 greg 2.3 GLYPH *gl;
307 greg 1.1 int tx0, ty0;
308     {
309     int n;
310 greg 2.3 register GORD *gp;
311 greg 1.1 int p0[2], p1[2];
312    
313     if (gl == NULL)
314     return;
315    
316 greg 2.3 n = gl->nverts;
317     gp = gvlist(gl);
318     mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
319 greg 1.1 while (n--) {
320 greg 2.3 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
321 greg 1.1 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
322     p0[0] = p1[0]; p0[1] = p1[1];
323 greg 2.3 gp += 2;
324 greg 1.1 }
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 greg 2.5 COLR pixval[SSS*SSS+1]; /* possible pixel values */
396     COLOR ctmp0, ctmp1;
397 greg 2.13 double d;
398 greg 1.1 COLR *scanout;
399 greg 2.5 int x, y;
400     register int i, j;
401     int cnt;
402 greg 1.1 register int inglyph;
403    
404 greg 2.5 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
405 greg 1.1
406 greg 2.5 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 greg 1.1 }
420 greg 2.5 for (y = ysiz/SSS-1; y >= 0; y--) {
421 greg 1.1 inglyph = 0;
422 greg 2.5 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 greg 1.1 }
433 greg 2.5 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
434 greg 1.1 fprintf(stderr, "write error in writemap\n");
435     exit(1);
436     }
437     }
438 greg 2.18 free((void *)scanout);
439 greg 1.1 }