ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.11
Committed: Wed Jul 8 13:58:10 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.10: +10 -3 lines
Log Message:
made it so just one of -x or -y can be given along with -h

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