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

# Content
1 /* Copyright (c) 1991 Regents of the University of California */
2
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 #include "standard.h"
14
15 #include "color.h"
16
17 #include "font.h"
18
19 #ifndef SSS
20 #define SSS 3 /* super-sample size */
21 #endif
22
23 #define MAXLINE 512 /* longest allowable line */
24
25 #ifndef DEFPATH
26 #define DEFPATH ":/usr/local/lib/ray"
27 #endif
28 #ifndef ULIBVAR
29 #define ULIBVAR "RAYPATH"
30 #endif
31
32 char *fontfile = "helvet.fnt"; /* our font file */
33
34 COLOR bgcolor = WHTCOLOR; /* background color */
35 COLOR fgcolor = BLKCOLOR; /* foreground color */
36
37 int direct = 'r'; /* direction (right, up, left, down) */
38
39 int cheight = 32*SSS; /* character height */
40 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 FONT *ourfont; /* our font */
54
55 char *libpath; /* library search path */
56
57 typedef struct line {
58 char *s; /* line w/o LF */
59 short *sp; /* character spacing */
60 struct line *next; /* next line up */
61 } LINE;
62
63 LINE *ourtext; /* our text */
64 int nlines, maxline; /* text dimensions */
65 int maxwidth; /* maximum line width (dvi) */
66
67 extern char *getenv();
68 extern char *malloc(), *calloc();
69
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 setcolor(fgcolor, atof(argv[an+1]),
83 atof(argv[an+2]),
84 atof(argv[an+3]));
85 an += 3;
86 break;
87 case 'b': /* background */
88 setcolor(bgcolor, atof(argv[an+1]),
89 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 cheight = atoi(argv[++an])*SSS;
114 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 /* load font file */
125 if ((libpath = getenv(ULIBVAR)) == NULL)
126 libpath = DEFPATH;
127 ourfont = getfont(fontfile);
128 /* 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 fputformat(COLRFMT, stdout);
141 putchar('\n');
142 /* 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 xsiz = (long)maxwidth*cwidth >> 8;
154 ysiz = nlines*cheight;
155 } else { /* reverse orientation */
156 xsiz = nlines*cheight;
157 ysiz = (long)maxwidth*cwidth >> 8;
158 }
159 if (xsiz % SSS)
160 xsiz += SSS - xsiz%SSS;
161 if (ysiz % SSS)
162 ysiz += SSS - ysiz%SSS;
163 xdim = (xsiz+7)/8;
164 ourbitmap = (BYTE *)calloc(ysiz, xdim);
165 if (ourbitmap == NULL)
166 error(SYSTEM, "Out of memory in makemap");
167 }
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 maxwidth = 0;
180 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 curl->s = malloc(len);
187 curl->sp = (short *)malloc(sizeof(short)*len--);
188 if (curl->s == NULL | curl->sp == NULL)
189 goto memerr;
190 if (len > maxline)
191 maxline = len;
192 strncpy(curl->s, buf, len);
193 curl->s[len] = '\0';
194 len = uniftext(curl->sp, curl->s, ourfont);
195 if (len > maxwidth)
196 maxwidth = len;
197 curl->next = ourtext;
198 ourtext = curl;
199 nlines++;
200 }
201 return;
202 memerr:
203 error(SYSTEM, "Out of memory in gettext");
204 }
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 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
228 if (ourtext->sp == NULL)
229 goto memerr;
230 maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont, 50);
231 nlines = 1;
232 return;
233 memerr:
234 error(SYSTEM, "Out of memory in arg_text");
235 }
236
237
238 maptext() /* map our text */
239 {
240 register LINE *curl;
241 int l, len;
242 register int i, c;
243
244 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 }
252
253
254 mapglyph(gl, tx0, ty0) /* convert a glyph */
255 GLYPH *gl;
256 int tx0, ty0;
257 {
258 int n;
259 register GORD *gp;
260 int p0[2], p1[2];
261
262 if (gl == NULL)
263 return;
264
265 n = gl->nverts;
266 gp = gvlist(gl);
267 mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
268 while (n--) {
269 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
270 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
271 p0[0] = p1[0]; p0[1] = p1[1];
272 gp += 2;
273 }
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 COLR pixval[SSS*SSS+1]; /* possible pixel values */
345 COLOR ctmp0, ctmp1;
346 double d;
347 COLR *scanout;
348 int x, y;
349 register int i, j;
350 int cnt;
351 register int inglyph;
352
353 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
354
355 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 }
369 for (y = ysiz/SSS-1; y >= 0; y--) {
370 inglyph = 0;
371 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 }
382 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
383 fprintf(stderr, "write error in writemap\n");
384 exit(1);
385 }
386 }
387 free((char *)scanout);
388 }