--- ray/src/px/psign.c 1991/05/30 08:22:52 1.3 +++ ray/src/px/psign.c 1992/07/07 18:24:34 2.10 @@ -1,4 +1,4 @@ -/* Copyright (c) 1991 Regents of the University of California */ +/* Copyright (c) 1992 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -10,21 +10,35 @@ static char SCCSid[] = "$SunId$ LBL"; * 7/1/87 */ -#include +#include "standard.h" #include "color.h" +#include "font.h" + +#ifndef SSS +#define SSS 3 /* super-sample size */ +#endif + #define MAXLINE 512 /* longest allowable line */ +#ifndef DEFPATH +#define DEFPATH ":/usr/local/lib/ray" +#endif +#ifndef ULIBVAR +#define ULIBVAR "RAYPATH" +#endif + char *fontfile = "helvet.fnt"; /* our font file */ -COLR bgcolr = WHTCOLR; /* background color */ -COLR fgcolr = BLKCOLR; /* foreground color */ +COLOR bgcolor = WHTCOLOR; /* background color */ +COLOR fgcolor = BLKCOLOR; /* foreground color */ int direct = 'r'; /* direction (right, up, left, down) */ -int cheight = 32; /* character height */ +int cheight = 32*SSS; /* character height */ double aspect = 1.67; /* height/width character aspect */ +double spacing = 0.0; /* character spacing */ int cwidth; /* computed character width */ unsigned char *ourbitmap; /* our output bitmap */ @@ -37,27 +51,27 @@ int xdim; /* size of horizontal scan (bytes) */ #define clrbit(x,y) bitop(x,y,&=~) #define tglbit(x,y) bitop(x,y,^=) -typedef unsigned char GLYPH; +FONT *ourfont; /* our font */ -GLYPH *ourfont[128]; /* our font */ +char *libpath; /* library search path */ typedef struct line { char *s; /* line w/o LF */ + short *sp; /* character spacing */ struct line *next; /* next line up */ } LINE; LINE *ourtext; /* our text */ int nlines, maxline; /* text dimensions */ +int maxwidth; /* maximum line width (dvi) */ -extern char *malloc(), *calloc(); -extern FILE *fropen(); +extern char *getenv(); main(argc, argv) int argc; char *argv[]; { - double atof(); int an; for (an = 1; an < argc && argv[an][0] == '-'; an++) @@ -65,13 +79,13 @@ char *argv[]; case 'c': /* color */ switch (argv[an][2]) { case 'f': /* foreground */ - setcolr(fgcolr, atof(argv[an+1]), + setcolor(fgcolor, atof(argv[an+1]), atof(argv[an+2]), atof(argv[an+3])); an += 3; break; case 'b': /* background */ - setcolr(bgcolr, atof(argv[an+1]), + setcolor(bgcolor, atof(argv[an+1]), atof(argv[an+2]), atof(argv[an+3])); an += 3; @@ -95,18 +109,32 @@ char *argv[]; goto unkopt; } break; + case 'x': /* x resolution */ + xsiz = atoi(argv[++an])*SSS; + break; + case 'y': + ysiz = atoi(argv[++an])*SSS; + break; case 'h': /* height of characters */ - cheight = atoi(argv[++an]); + cheight = atoi(argv[++an])*SSS; + xsiz = xsiz = 0; break; case 'a': /* aspect ratio */ aspect = atof(argv[++an]); break; + case 's': /* spacing */ + spacing = atof(argv[++an]); + break; default:; unkopt: fprintf(stderr, "%s: unknown option: %s\n", argv[0], argv[an]); exit(1); } + /* load font file */ + if ((libpath = getenv(ULIBVAR)) == NULL) + libpath = DEFPATH; + ourfont = getfont(fontfile); /* get text */ if (an == argc) gettext(stdin); @@ -115,8 +143,6 @@ unkopt: /* create bit map */ makemap(); - /* load font file */ - loadfont(); /* convert text to bitmap */ maptext(); /* print header */ @@ -132,76 +158,59 @@ unkopt: makemap() /* create the bit map */ { - cwidth = cheight/aspect + 0.5; + double pictaspect; + if (direct == 'r' || direct == 'l') { - xsiz = maxline*cwidth; - ysiz = nlines*cheight; + if (xsiz == 0 || ysiz == 0) { + cwidth = cheight/aspect + 0.5; + xsiz = (long)maxwidth*cwidth >> 8; + ysiz = nlines*cheight; + } else if (aspect > FTINY) { + pictaspect = 256*nlines*aspect/maxwidth; + if (pictaspect*xsiz < ysiz) + ysiz = pictaspect*xsiz + 0.5; + else + xsiz = ysiz/pictaspect + 0.5; + cheight = ysiz/nlines; + cwidth = cheight/aspect + 0.5; + } else { + pictaspect = (double)ysiz/xsiz; + aspect = pictaspect*maxwidth/(256*nlines); + cheight = ysiz/nlines; + cwidth = cheight/aspect + 0.5; + } } else { /* reverse orientation */ - xsiz = nlines*cheight; - ysiz = maxline*cwidth; + if (xsiz == 0 || ysiz == 0) { + cwidth = cheight/aspect + 0.5; + xsiz = nlines*cheight; + ysiz = (long)maxwidth*cwidth >> 8; + } else if (aspect > FTINY) { + pictaspect = maxwidth/(256*nlines*aspect); + if (pictaspect*xsiz < ysiz) + ysiz = pictaspect*xsiz + 0.5; + else + xsiz = ysiz/pictaspect + 0.5; + cheight = xsiz/nlines; + cwidth = cheight/aspect + 0.5; + } else { + pictaspect = (double)ysiz/xsiz; + aspect = maxwidth/(256*nlines*pictaspect); + cheight = xsiz/nlines; + cwidth = cheight/aspect + 0.5; + } } + if (xsiz % SSS) + xsiz += SSS - xsiz%SSS; + if (ysiz % SSS) + ysiz += SSS - ysiz%SSS; xdim = (xsiz+7)/8; - ourbitmap = (BYTE *)calloc(ysiz, xdim); - if (ourbitmap == NULL) { - fprintf(stderr, "out of memory in makemap\n"); - exit(1); - } + ourbitmap = (BYTE *)bmalloc(ysiz*xdim); + if (ourbitmap == NULL) + error(SYSTEM, "Out of memory in makemap"); + bzero((char *)ourbitmap, ysiz*xdim); } -loadfont() /* load the font file */ -{ - FILE *fp; - char *err; - int gn, ngv, gv; - register GLYPH *g; - - if ((fp = fropen(fontfile)) == NULL) { - fprintf(stderr, "cannot find font file \"%s\"\n", - fontfile); - exit(1); - } - while (fscanf(fp, "%d", &gn) == 1) { /* get each glyph */ - if (gn < 0 || gn > 127) { - err = "illegal"; - goto fonterr; - } - if (ourfont[gn] != NULL) { - err = "duplicate"; - goto fonterr; - } - if (fscanf(fp, "%d", &ngv) != 1 || - ngv < 0 || ngv > 255) { - err = "bad # vertices for"; - goto fonterr; - } - g = (GLYPH *)malloc((2*ngv+1)*sizeof(GLYPH)); - if (g == NULL) - goto memerr; - ourfont[gn] = g; - *g++ = ngv; - ngv *= 2; - while (ngv--) { - if (fscanf(fp, "%d", &gv) != 1 || - gv < 0 || gv > 255) { - err = "bad vertex for"; - goto fonterr; - } - *g++ = gv; - } - } - fclose(fp); - return; -fonterr: - fprintf(stderr, "%s character (%d) in font file \"%s\"\n", - err, gn, fontfile); - exit(1); -memerr: - fprintf(stderr, "out of memory in loadfont\n"); - exit(1); -} - - gettext(fp) /* get text from a file */ FILE *fp; { @@ -211,27 +220,38 @@ FILE *fp; int len; maxline = 0; + maxwidth = 0; nlines = 0; while (fgets(buf, MAXLINE, fp) != NULL) { curl = (LINE *)malloc(sizeof(LINE)); if (curl == NULL) goto memerr; len = strlen(buf); - curl->s = malloc(len--); - if (curl->s == NULL) + curl->s = malloc(len); + curl->sp = (short *)malloc(sizeof(short)*len--); + if (curl->s == NULL | curl->sp == NULL) goto memerr; + if (len > maxline) + maxline = len; strncpy(curl->s, buf, len); curl->s[len] = '\0'; + if (spacing < -1./256.) + len = squeeztext(curl->sp, curl->s, ourfont, + (int)(spacing*-256.0)); + else if (spacing > 1./256.) + len = proptext(curl->sp, curl->s, ourfont, + (int)(spacing*256.0), 3); + else + len = uniftext(curl->sp, curl->s, ourfont); + if (len > maxwidth) + maxwidth = len; curl->next = ourtext; ourtext = curl; - if (len > maxline) - maxline = len; nlines++; } return; memerr: - fprintf(stderr, "out of memory in gettext\n"); - exit(1); + error(SYSTEM, "Out of memory in gettext"); } @@ -255,44 +275,59 @@ char *av[]; *--cp = '\0'; ourtext->next = NULL; maxline = strlen(ourtext->s); + ourtext->sp = (short *)malloc(sizeof(short)*(maxline+1)); + if (ourtext->sp == NULL) + goto memerr; + if (spacing < 0.0) + maxwidth = squeeztext(ourtext->sp, ourtext->s, ourfont, + (int)(spacing*-256.0)); + else if (spacing > 0.0) + maxwidth = proptext(ourtext->sp, ourtext->s, ourfont, + (int)(spacing*256.0), 3); + else + maxwidth = uniftext(ourtext->sp, ourtext->s, ourfont); nlines = 1; return; memerr: - fprintf(stderr, "out of memory in arg_text\n"); - exit(1); + error(SYSTEM, "Out of memory in arg_text"); } maptext() /* map our text */ { register LINE *curl; - int l; - register int c; + int l, len; + register int i, c; - for (l = 0, curl = ourtext; curl != NULL; l++, curl = curl->next) - for (c = strlen(curl->s)-1; c >= 0; c--) - mapglyph(ourfont[curl->s[c]], c, l); + for (l = 0, curl = ourtext; curl != NULL; l += 256, curl = curl->next) { + len = strlen(curl->s); c = 0; + for (i = 0; i < len; i++) { + c += curl->sp[i]; + mapglyph(ourfont->fg[curl->s[i]&0xff], c, l); + } + } } mapglyph(gl, tx0, ty0) /* convert a glyph */ -register GLYPH *gl; +GLYPH *gl; int tx0, ty0; { int n; + register GORD *gp; int p0[2], p1[2]; if (gl == NULL) return; - tx0 <<= 8; ty0 <<= 8; - n = *gl++; - mapcoord(p0, gl[2*n-2]+tx0, gl[2*n-1]+ty0); + n = gl->nverts; + gp = gvlist(gl); + mapcoord(p0, gp[2*n-2]+tx0, gp[2*n-1]+ty0); while (n--) { - mapcoord(p1, gl[0]+tx0, gl[1]+ty0); + mapcoord(p1, gp[0]+tx0, gp[1]+ty0); mapedge(p0[0], p0[1], p1[0]-p0[0], p1[1]-p0[1]); p0[0] = p1[0]; p0[1] = p1[1]; - gl += 2; + gp += 2; } } @@ -364,29 +399,45 @@ int run, rise; writemap(fp) /* write out bitmap */ FILE *fp; { + COLR pixval[SSS*SSS+1]; /* possible pixel values */ + COLOR ctmp0, ctmp1; + double d; COLR *scanout; - int y; - register int x; + int x, y; + register int i, j; + int cnt; register int inglyph; - fprintf(fp, "-Y %d +X %d\n", ysiz, xsiz); + fprintf(fp, "-Y %d +X %d\n", ysiz/SSS, xsiz/SSS); - scanout = (COLR *)malloc(xsiz*sizeof(COLR)); - if (scanout == NULL) { - fprintf(stderr, "out of memory in writemap\n"); - exit(1); + scanout = (COLR *)malloc(xsiz/SSS*sizeof(COLR)); + if (scanout == NULL) + error(SYSTEM, "Out of memory in writemap"); + for (i = 0; i <= SSS*SSS; i++) { /* compute possible values */ + copycolor(ctmp0, fgcolor); + d = (double)i/(SSS*SSS); + scalecolor(ctmp0, d); + copycolor(ctmp1, bgcolor); + d = 1.0 - d; + scalecolor(ctmp1, d); + addcolor(ctmp0, ctmp1); + setcolr(pixval[i], colval(ctmp0,RED), + colval(ctmp0,GRN), colval(ctmp0,BLU)); } - for (y = ysiz-1; y >= 0; y--) { + for (y = ysiz/SSS-1; y >= 0; y--) { inglyph = 0; - for (x = 0; x < xsiz; x++) { - if (tstbit(x, y)) - inglyph ^= 1; - if (inglyph) - copycolr(scanout[x], fgcolr); - else - copycolr(scanout[x], bgcolr); + for (x = 0; x < xsiz/SSS; x++) { + cnt = 0; + for (j = 0; j < SSS; j++) + for (i = 0; i < SSS; i++) { + if (tstbit(x*SSS+i, y*SSS+j)) + inglyph ^= 1<