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 (32 years, 4 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

# 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 double spacing = 0.0; /* character spacing */
42 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 FONT *ourfont; /* our font */
55
56 char *libpath; /* library search path */
57
58 typedef struct line {
59 char *s; /* line w/o LF */
60 short *sp; /* character spacing */
61 struct line *next; /* next line up */
62 } LINE;
63
64 LINE *ourtext; /* our text */
65 int nlines, maxline; /* text dimensions */
66 int maxwidth; /* maximum line width (dvi) */
67
68 extern char *getenv();
69 extern char *malloc(), *calloc();
70
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 setcolor(fgcolor, atof(argv[an+1]),
84 atof(argv[an+2]),
85 atof(argv[an+3]));
86 an += 3;
87 break;
88 case 'b': /* background */
89 setcolor(bgcolor, atof(argv[an+1]),
90 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 cheight = atoi(argv[++an])*SSS;
115 break;
116 case 'a': /* aspect ratio */
117 aspect = atof(argv[++an]);
118 break;
119 case 's': /* spacing */
120 spacing = atof(argv[++an]);
121 break;
122 default:;
123 unkopt:
124 fprintf(stderr, "%s: unknown option: %s\n",
125 argv[0], argv[an]);
126 exit(1);
127 }
128 /* load font file */
129 if ((libpath = getenv(ULIBVAR)) == NULL)
130 libpath = DEFPATH;
131 ourfont = getfont(fontfile);
132 /* 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 fputformat(COLRFMT, stdout);
145 putchar('\n');
146 /* 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 xsiz = (long)maxwidth*cwidth >> 8;
158 ysiz = nlines*cheight;
159 } else { /* reverse orientation */
160 xsiz = nlines*cheight;
161 ysiz = (long)maxwidth*cwidth >> 8;
162 }
163 if (xsiz % SSS)
164 xsiz += SSS - xsiz%SSS;
165 if (ysiz % SSS)
166 ysiz += SSS - ysiz%SSS;
167 xdim = (xsiz+7)/8;
168 ourbitmap = (BYTE *)calloc(ysiz, xdim);
169 if (ourbitmap == NULL)
170 error(SYSTEM, "Out of memory in makemap");
171 }
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 maxwidth = 0;
184 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 curl->s = malloc(len);
191 curl->sp = (short *)malloc(sizeof(short)*len--);
192 if (curl->s == NULL | curl->sp == NULL)
193 goto memerr;
194 if (len > maxline)
195 maxline = len;
196 strncpy(curl->s, buf, len);
197 curl->s[len] = '\0';
198 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 if (len > maxwidth)
207 maxwidth = len;
208 curl->next = ourtext;
209 ourtext = curl;
210 nlines++;
211 }
212 return;
213 memerr:
214 error(SYSTEM, "Out of memory in gettext");
215 }
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 ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1));
239 if (ourtext->sp == NULL)
240 goto memerr;
241 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 nlines = 1;
250 return;
251 memerr:
252 error(SYSTEM, "Out of memory in arg_text");
253 }
254
255
256 maptext() /* map our text */
257 {
258 register LINE *curl;
259 int l, len;
260 register int i, c;
261
262 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 }
270
271
272 mapglyph(gl, tx0, ty0) /* convert a glyph */
273 GLYPH *gl;
274 int tx0, ty0;
275 {
276 int n;
277 register GORD *gp;
278 int p0[2], p1[2];
279
280 if (gl == NULL)
281 return;
282
283 n = gl->nverts;
284 gp = gvlist(gl);
285 mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0);
286 while (n--) {
287 mapcoord(p1, gp[0]+tx0, gp[1]+ty0);
288 mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]);
289 p0[0] = p1[0]; p0[1] = p1[1];
290 gp += 2;
291 }
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 COLR pixval[SSS*SSS+1]; /* possible pixel values */
363 COLOR ctmp0, ctmp1;
364 double d;
365 COLR *scanout;
366 int x, y;
367 register int i, j;
368 int cnt;
369 register int inglyph;
370
371 fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS);
372
373 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 }
387 for (y = ysiz/SSS-1; y >= 0; y--) {
388 inglyph = 0;
389 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 }
400 if (fwritecolrs(scanout, xsiz/SSS, fp) < 0) {
401 fprintf(stderr, "write error in writemap\n");
402 exit(1);
403 }
404 }
405 free((char *)scanout);
406 }