ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.16
Committed: Mon Feb 28 09:25:31 1994 UTC (30 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.15: +1 -0 lines
Log Message:
added newheader() call

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