ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.6
Committed: Tue Jun 16 16:48:39 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +20 -2 lines
Log Message:
added -s option to psign for proportionally spaced text

File Contents

# User Rev Content
1 greg 1.3 /* Copyright (c) 1991 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.2 extern char *malloc(), *calloc();
70 greg 1.1
71    
72     main(argc, argv)
73     int argc;
74     char *argv[];
75     {
76     int an;
77    
78     for (an = 1; an < argc && argv[an][0] == '-'; an++)
79     switch (argv[an][1]) {
80     case 'c': /* color */
81     switch (argv[an][2]) {
82     case 'f': /* foreground */
83 greg 2.5 setcolor(fgcolor, atof(argv[an+1]),
84 greg 1.1 atof(argv[an+2]),
85     atof(argv[an+3]));
86     an += 3;
87     break;
88     case 'b': /* background */
89 greg 2.5 setcolor(bgcolor, atof(argv[an+1]),
90 greg 1.1 atof(argv[an+2]),
91     atof(argv[an+3]));
92     an += 3;
93     break;
94     default:
95     goto unkopt;
96     }
97     break;
98     case 'f': /* font */
99     fontfile = argv[++an];
100     break;
101     case 'd': /* direction */
102     switch (argv[an][2]) {
103     case 'r': /* right */
104     case 'u': /* up */
105     case 'l': /* left */
106     case 'd': /* down */
107     direct = argv[an][2];
108     break;
109     default:
110     goto unkopt;
111     }
112     break;
113     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     printargs(argc, argv, stdout);
144 greg 1.3 fputformat(COLRFMT, stdout);
145     putchar('\n');
146 greg 1.1 /* write out bitmap */
147     writemap(stdout);
148    
149     exit(0);
150     }
151    
152    
153     makemap() /* create the bit map */
154     {
155     cwidth = cheight/aspect + 0.5;
156     if (direct == 'r' || direct == 'l') {
157 greg 2.5 xsiz = (long)maxwidth*cwidth >> 8;
158 greg 1.1 ysiz = nlines*cheight;
159     } else { /* reverse orientation */
160     xsiz = nlines*cheight;
161 greg 2.5 ysiz = (long)maxwidth*cwidth >> 8;
162 greg 1.1 }
163 greg 2.5 if (xsiz % SSS)
164     xsiz += SSS - xsiz%SSS;
165     if (ysiz % SSS)
166     ysiz += SSS - ysiz%SSS;
167 greg 1.1 xdim = (xsiz+7)/8;
168     ourbitmap = (BYTE *)calloc(ysiz, xdim);
169 greg 2.5 if (ourbitmap == NULL)
170     error(SYSTEM, "Out of memory in makemap");
171 greg 1.1 }
172    
173    
174     gettext(fp) /* get text from a file */
175     FILE *fp;
176     {
177     char *fgets();
178     char buf[MAXLINE];
179     register LINE *curl;
180     int len;
181    
182     maxline = 0;
183 greg 2.4 maxwidth = 0;
184 greg 1.1 nlines = 0;
185     while (fgets(buf, MAXLINE, fp) != NULL) {
186     curl = (LINE *)malloc(sizeof(LINE));
187     if (curl == NULL)
188     goto memerr;
189     len = strlen(buf);
190 greg 2.4 curl->s = malloc(len);
191     curl->sp = (short *)malloc(sizeof(short)*len--);
192     if (curl->s == NULL | curl->sp == NULL)
193 greg 1.1 goto memerr;
194 greg 2.4 if (len > maxline)
195     maxline = len;
196 greg 1.1 strncpy(curl->s, buf, len);
197     curl->s[len] = '\0';
198 greg 2.6 if (spacing < 0.0)
199     len = squeeztext(curl->sp, curl->s, ourfont,
200     (int)(spacing*-256.0));
201     else if (spacing > 0.0)
202     len = proptext(curl->sp, curl->s, ourfont,
203     (int)(spacing*256.0), 3);
204     else
205     len = uniftext(curl->sp, curl->s, ourfont);
206 greg 2.4 if (len > maxwidth)
207     maxwidth = len;
208 greg 1.1 curl->next = ourtext;
209     ourtext = curl;
210     nlines++;
211     }
212     return;
213     memerr:
214 greg 2.5 error(SYSTEM, "Out of memory in gettext");
215 greg 1.1 }
216    
217    
218     arg_text(ac, av) /* get text from arguments */
219     int ac;
220     char *av[];
221     {
222     register char *cp;
223    
224     ourtext = (LINE *)malloc(sizeof(LINE));
225     if (ourtext == NULL)
226     goto memerr;
227     ourtext->s = malloc(MAXLINE);
228     if (ourtext->s == NULL)
229     goto memerr;
230     for (cp = ourtext->s; ac-- > 0; av++) {
231     strcpy(cp, *av);
232     cp += strlen(*av);
233     *cp++ = ' ';
234     }
235     *--cp = '\0';
236     ourtext->next = NULL;
237     maxline = strlen(ourtext->s);
238 greg 2.4 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
239     if (ourtext->sp == NULL)
240     goto memerr;
241 greg 2.6 if (spacing < 0.0)
242     maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont,
243     (int)(spacing*-256.0));
244     else if (spacing > 0.0)
245     maxwidth = proptext(ourtext->sp, ourtext->s, ourfont,
246     (int)(spacing*256.0), 3);
247     else
248     maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont);
249 greg 1.1 nlines = 1;
250     return;
251     memerr:
252 greg 2.5 error(SYSTEM, "Out of memory in arg_text");
253 greg 1.1 }
254    
255    
256     maptext() /* map our text */
257     {
258     register LINE *curl;
259 greg 2.4 int l, len;
260     register int i, c;
261 greg 1.1
262 greg 2.4 for (l = 0, curl = ourtext; curl != NULL; l += 256, curl = curl->next) {
263     len = strlen(curl->s); c = 0;
264     for (i = 0; i < len; i++) {
265     c += curl->sp[i];
266     mapglyph(ourfont->fg[curl->s[i]&0xff], c, l);
267     }
268     }
269 greg 1.1 }
270    
271    
272     mapglyph(gl, tx0, ty0) /* convert a glyph */
273 greg 2.3 GLYPH *gl;
274 greg 1.1 int tx0, ty0;
275     {
276     int n;
277 greg 2.3 register GORD *gp;
278 greg 1.1 int p0[2], p1[2];
279    
280     if (gl == NULL)
281     return;
282    
283 greg 2.3 n = gl->nverts;
284     gp = gvlist(gl);
285     mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
286 greg 1.1 while (n--) {
287 greg 2.3 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
288 greg 1.1 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
289     p0[0] = p1[0]; p0[1] = p1[1];
290 greg 2.3 gp += 2;
291 greg 1.1 }
292     }
293    
294    
295     mapcoord(p, tx, ty) /* map text to picture coordinates */
296     int p[2], tx, ty;
297     {
298     tx = (long)tx*cwidth >> 8;
299     ty = (long)ty*cheight >> 8;
300    
301     switch (direct) {
302     case 'r': /* right */
303     p[0] = tx;
304     p[1] = ty;
305     return;
306     case 'u': /* up */
307     p[0] = xsiz-1-ty;
308     p[1] = tx;
309     return;
310     case 'l': /* left */
311     p[0] = xsiz-1-tx;
312     p[1] = ysiz-1-ty;
313     return;
314     case 'd': /* down */
315     p[0] = ty;
316     p[1] = ysiz-1-tx;
317     return;
318     }
319     }
320    
321    
322     mapedge(x, y, run, rise) /* map an edge */
323     register int x, y;
324     int run, rise;
325     {
326     int xstep;
327     int rise2, run2;
328     int n;
329    
330     if (rise == 0)
331     return;
332     /* always draw up */
333     if (rise < 0) {
334     x += run;
335     y += rise;
336     rise = -rise;
337     run = -run;
338     }
339     if (run < 0) {
340     xstep = -1;
341     run = -run;
342     } else
343     xstep = 1;
344     n = rise;
345     run2 = rise2 = 0;
346     while (n)
347     if (rise2 >= run2) {
348     tglbit(x, y);
349     n--;
350     y++;
351     run2 += run;
352     } else {
353     x += xstep;
354     rise2 += rise;
355     }
356     }
357    
358    
359     writemap(fp) /* write out bitmap */
360     FILE *fp;
361     {
362 greg 2.5 COLR pixval[SSS*SSS+1]; /* possible pixel values */
363     COLOR ctmp0, ctmp1;
364     double d;
365 greg 1.1 COLR *scanout;
366 greg 2.5 int x, y;
367     register int i, j;
368     int cnt;
369 greg 1.1 register int inglyph;
370    
371 greg 2.5 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
372 greg 1.1
373 greg 2.5 scanout = (COLR *)malloc(xsiz/SSS*sizeof(COLR));
374     if (scanout == NULL)
375     error(SYSTEM, "Out of memory in writemap");
376     for (i = 0; i <= SSS*SSS; i++) { /* compute possible values */
377     copycolor(ctmp0, fgcolor);
378     d = (double)i/(SSS*SSS);
379     scalecolor(ctmp0, d);
380     copycolor(ctmp1, bgcolor);
381     d = 1.0 - d;
382     scalecolor(ctmp1, d);
383     addcolor(ctmp0, ctmp1);
384     setcolr(pixval[i], colval(ctmp0,RED),
385     colval(ctmp0,GRN), colval(ctmp0,BLU));
386 greg 1.1 }
387 greg 2.5 for (y = ysiz/SSS-1; y >= 0; y--) {
388 greg 1.1 inglyph = 0;
389 greg 2.5 for (x = 0; x < xsiz/SSS; x++) {
390     cnt = 0;
391     for (j = 0; j < SSS; j++)
392     for (i = 0; i < SSS; i++) {
393     if (tstbit(x*SSS+i, y*SSS+j))
394     inglyph ^= 1<<j;
395     if (inglyph & 1<<j)
396     cnt++;
397     }
398     copycolr(scanout[x], pixval[cnt]);
399 greg 1.1 }
400 greg 2.5 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
401 greg 1.1 fprintf(stderr, "write error in writemap\n");
402     exit(1);
403     }
404     }
405     free((char *)scanout);
406     }