ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.5
Committed: Tue Jun 16 16:27:37 1992 UTC (31 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.4: +52 -34 lines
Log Message:
added super-sampling for anti-aliasing of 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     int cwidth; /* computed character width */
42    
43     unsigned char *ourbitmap; /* our output bitmap */
44     int xsiz, ysiz; /* bitmap dimensions */
45     int xdim; /* size of horizontal scan (bytes) */
46    
47     #define bitop(x,y,op) (ourbitmap[(y)*xdim+((x)>>3)] op (1<<((x)&7)))
48     #define tstbit(x,y) bitop(x,y,&)
49     #define setbit(x,y) bitop(x,y,|=)
50     #define clrbit(x,y) bitop(x,y,&=~)
51     #define tglbit(x,y) bitop(x,y,^=)
52    
53 greg 2.3 FONT *ourfont; /* our font */
54 greg 1.1
55 greg 2.3 char *libpath; /* library search path */
56    
57 greg 1.1 typedef struct line {
58     char *s; /* line w/o LF */
59 greg 2.4 short *sp; /* character spacing */
60 greg 1.1 struct line *next; /* next line up */
61     } LINE;
62    
63     LINE *ourtext; /* our text */
64     int nlines, maxline; /* text dimensions */
65 greg 2.4 int maxwidth; /* maximum line width (dvi) */
66 greg 1.1
67 greg 2.3 extern char *getenv();
68 greg 1.2 extern char *malloc(), *calloc();
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     case 'h': /* height of characters */
113 greg 2.5 cheight = atoi(argv[++an])*SSS;
114 greg 1.1 break;
115     case 'a': /* aspect ratio */
116     aspect = atof(argv[++an]);
117     break;
118     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     if ((libpath = getenv(ULIBVAR)) == NULL)
126     libpath = DEFPATH;
127     ourfont = getfont(fontfile);
128 greg 1.1 /* get text */
129     if (an == argc)
130     gettext(stdin);
131     else
132     arg_text(argc-an, argv+an);
133    
134     /* create bit map */
135     makemap();
136     /* convert text to bitmap */
137     maptext();
138     /* print header */
139     printargs(argc, argv, stdout);
140 greg 1.3 fputformat(COLRFMT, stdout);
141     putchar('\n');
142 greg 1.1 /* write out bitmap */
143     writemap(stdout);
144    
145     exit(0);
146     }
147    
148    
149     makemap() /* create the bit map */
150     {
151     cwidth = cheight/aspect + 0.5;
152     if (direct == 'r' || direct == 'l') {
153 greg 2.5 xsiz = (long)maxwidth*cwidth >> 8;
154 greg 1.1 ysiz = nlines*cheight;
155     } else { /* reverse orientation */
156     xsiz = nlines*cheight;
157 greg 2.5 ysiz = (long)maxwidth*cwidth >> 8;
158 greg 1.1 }
159 greg 2.5 if (xsiz % SSS)
160     xsiz += SSS - xsiz%SSS;
161     if (ysiz % SSS)
162     ysiz += SSS - ysiz%SSS;
163 greg 1.1 xdim = (xsiz+7)/8;
164     ourbitmap = (BYTE *)calloc(ysiz, xdim);
165 greg 2.5 if (ourbitmap == NULL)
166     error(SYSTEM, "Out of memory in makemap");
167 greg 1.1 }
168    
169    
170     gettext(fp) /* get text from a file */
171     FILE *fp;
172     {
173     char *fgets();
174     char buf[MAXLINE];
175     register LINE *curl;
176     int len;
177    
178     maxline = 0;
179 greg 2.4 maxwidth = 0;
180 greg 1.1 nlines = 0;
181     while (fgets(buf, MAXLINE, fp) != NULL) {
182     curl = (LINE *)malloc(sizeof(LINE));
183     if (curl == NULL)
184     goto memerr;
185     len = strlen(buf);
186 greg 2.4 curl->s = malloc(len);
187     curl->sp = (short *)malloc(sizeof(short)*len--);
188     if (curl->s == NULL | curl->sp == NULL)
189 greg 1.1 goto memerr;
190 greg 2.4 if (len > maxline)
191     maxline = len;
192 greg 1.1 strncpy(curl->s, buf, len);
193     curl->s[len] = '\0';
194 greg 2.4 len = uniftext(curl->sp, curl->s, ourfont);
195     if (len > maxwidth)
196     maxwidth = len;
197 greg 1.1 curl->next = ourtext;
198     ourtext = curl;
199     nlines++;
200     }
201     return;
202     memerr:
203 greg 2.5 error(SYSTEM, "Out of memory in gettext");
204 greg 1.1 }
205    
206    
207     arg_text(ac, av) /* get text from arguments */
208     int ac;
209     char *av[];
210     {
211     register char *cp;
212    
213     ourtext = (LINE *)malloc(sizeof(LINE));
214     if (ourtext == NULL)
215     goto memerr;
216     ourtext->s = malloc(MAXLINE);
217     if (ourtext->s == NULL)
218     goto memerr;
219     for (cp = ourtext->s; ac-- > 0; av++) {
220     strcpy(cp, *av);
221     cp += strlen(*av);
222     *cp++ = ' ';
223     }
224     *--cp = '\0';
225     ourtext->next = NULL;
226     maxline = strlen(ourtext->s);
227 greg 2.4 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
228     if (ourtext->sp == NULL)
229     goto memerr;
230 greg 2.5 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont, 50);
231 greg 1.1 nlines = 1;
232     return;
233     memerr:
234 greg 2.5 error(SYSTEM, "Out of memory in arg_text");
235 greg 1.1 }
236    
237    
238     maptext() /* map our text */
239     {
240     register LINE *curl;
241 greg 2.4 int l, len;
242     register int i, c;
243 greg 1.1
244 greg 2.4 for (l = 0, curl = ourtext; curl != NULL; l += 256, curl = curl->next) {
245     len = strlen(curl->s); c = 0;
246     for (i = 0; i < len; i++) {
247     c += curl->sp[i];
248     mapglyph(ourfont->fg[curl->s[i]&0xff], c, l);
249     }
250     }
251 greg 1.1 }
252    
253    
254     mapglyph(gl, tx0, ty0) /* convert a glyph */
255 greg 2.3 GLYPH *gl;
256 greg 1.1 int tx0, ty0;
257     {
258     int n;
259 greg 2.3 register GORD *gp;
260 greg 1.1 int p0[2], p1[2];
261    
262     if (gl == NULL)
263     return;
264    
265 greg 2.3 n = gl->nverts;
266     gp = gvlist(gl);
267     mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
268 greg 1.1 while (n--) {
269 greg 2.3 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
270 greg 1.1 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
271     p0[0] = p1[0]; p0[1] = p1[1];
272 greg 2.3 gp += 2;
273 greg 1.1 }
274     }
275    
276    
277     mapcoord(p, tx, ty) /* map text to picture coordinates */
278     int p[2], tx, ty;
279     {
280     tx = (long)tx*cwidth >> 8;
281     ty = (long)ty*cheight >> 8;
282    
283     switch (direct) {
284     case 'r': /* right */
285     p[0] = tx;
286     p[1] = ty;
287     return;
288     case 'u': /* up */
289     p[0] = xsiz-1-ty;
290     p[1] = tx;
291     return;
292     case 'l': /* left */
293     p[0] = xsiz-1-tx;
294     p[1] = ysiz-1-ty;
295     return;
296     case 'd': /* down */
297     p[0] = ty;
298     p[1] = ysiz-1-tx;
299     return;
300     }
301     }
302    
303    
304     mapedge(x, y, run, rise) /* map an edge */
305     register int x, y;
306     int run, rise;
307     {
308     int xstep;
309     int rise2, run2;
310     int n;
311    
312     if (rise == 0)
313     return;
314     /* always draw up */
315     if (rise < 0) {
316     x += run;
317     y += rise;
318     rise = -rise;
319     run = -run;
320     }
321     if (run < 0) {
322     xstep = -1;
323     run = -run;
324     } else
325     xstep = 1;
326     n = rise;
327     run2 = rise2 = 0;
328     while (n)
329     if (rise2 >= run2) {
330     tglbit(x, y);
331     n--;
332     y++;
333     run2 += run;
334     } else {
335     x += xstep;
336     rise2 += rise;
337     }
338     }
339    
340    
341     writemap(fp) /* write out bitmap */
342     FILE *fp;
343     {
344 greg 2.5 COLR pixval[SSS*SSS+1]; /* possible pixel values */
345     COLOR ctmp0, ctmp1;
346     double d;
347 greg 1.1 COLR *scanout;
348 greg 2.5 int x, y;
349     register int i, j;
350     int cnt;
351 greg 1.1 register int inglyph;
352    
353 greg 2.5 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
354 greg 1.1
355 greg 2.5 scanout = (COLR *)malloc(xsiz/SSS*sizeof(COLR));
356     if (scanout == NULL)
357     error(SYSTEM, "Out of memory in writemap");
358     for (i = 0; i <= SSS*SSS; i++) { /* compute possible values */
359     copycolor(ctmp0, fgcolor);
360     d = (double)i/(SSS*SSS);
361     scalecolor(ctmp0, d);
362     copycolor(ctmp1, bgcolor);
363     d = 1.0 - d;
364     scalecolor(ctmp1, d);
365     addcolor(ctmp0, ctmp1);
366     setcolr(pixval[i], colval(ctmp0,RED),
367     colval(ctmp0,GRN), colval(ctmp0,BLU));
368 greg 1.1 }
369 greg 2.5 for (y = ysiz/SSS-1; y >= 0; y--) {
370 greg 1.1 inglyph = 0;
371 greg 2.5 for (x = 0; x < xsiz/SSS; x++) {
372     cnt = 0;
373     for (j = 0; j < SSS; j++)
374     for (i = 0; i < SSS; i++) {
375     if (tstbit(x*SSS+i, y*SSS+j))
376     inglyph ^= 1<<j;
377     if (inglyph & 1<<j)
378     cnt++;
379     }
380     copycolr(scanout[x], pixval[cnt]);
381 greg 1.1 }
382 greg 2.5 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
383 greg 1.1 fprintf(stderr, "write error in writemap\n");
384     exit(1);
385     }
386     }
387     free((char *)scanout);
388     }