ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/px/psign.c
Revision: 2.14
Committed: Fri Jan 8 13:14:14 1993 UTC (31 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.13: +10 -10 lines
Log Message:
removed dangerous rounding that caused right margin to be exceeded

File Contents

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