ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.17
Committed: Thu Apr 14 04:53:54 1994 UTC (30 years ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.16: +0 -6 lines
Log Message:
changed libpath to getlibpath()

File Contents

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