home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char ScrId[] = "@(#) vfonts.c:1.3";
- #endif
-
- /*****************************************************************
-
- Copyright 1985. All Rights Reserved Chris Lewis
-
- Module : vfonts.c 1.3
- Date submitted : 86/01/30 09:19:57
- Author : Chris Lewis
- Origin : Permission to copy and further distribute is
- freely given provided this copyright notice remains
- intact and that this software is not sold for profit.
- Description : Description of the file
- Modifications:
-
- - modified to work with the HP DeskJet printer, by maintaining
- each line in an internal buffer and then dumping it in one
- go. The original way of printing each character individually
- didn't work because the DeskJet cannot reverse feed the paper.
-
- - added draft-mode printing at 150 dpi. Problem is that with
- the bitmap you just can't mix fonts of different resolutions.
- The quick&dirty way out of this is to consider the low-ress
- option as binding (i.e. if you start low-res and you don't
- have the fonts, your job aborts!).
-
- ******************************************************************/
-
- #include <assert.h>
- #include <stdio.h>
- #include <fcntl.h>
- #ifdef UNIX
- #include <ctype.h>
- #include <vfont.h>
- #else
- #include <alloc.h>
- #include <mem.h>
- #include <vp/vfont.h>
- #endif
- #define LCAT
- #include "lcat.h"
-
- extern FILE *diagFile;
- extern FILE *outFile;
- #define DEBUGPRINTF if (diagFile) fprintf
- #define REGISTER /**/
- static char *fontFamily;
- #define FONTS "RIBS"
- char fpos[] = FONTS;
-
- #define STD_DPI 300
- static int dpi = STD_DPI;
- static int gl_dpi = STD_DPI;
-
- #define MAX_FONT 3
- #define SPEC_FONT 3
- #define IMG_SIZE (unsigned int)(50000)
-
- static long xpos = -1;
- static long ypos = -1;
-
- static struct header vf_header;
- struct fcache {
- int fnum; /* number of cached font (R=0, I=1, B=2, S=3) */
- int psize; /* pointsize of font */
- int count; /* usage counter for LRU caching */
- struct dispatch *dsp; /* font description table */
- u_char *image; /* font bitmaps */
- } fontcache[MAX_FONT];
-
- /*
- * following vars hold data for selected font
- */
- int cfnum, cpsize;
- struct dispatch *cdsp;
- u_char huge* imageTable;
- int use_count=1;
-
-
- /* raster related definitions */
- extern u_char raster[NLINES][RASTWIDTH];
- #define TRUE 1
- #define FALSE 0
- static int new_page = TRUE;
- static long y_base; /* vertical position of baseline for current line */
- static long max_up; /* max height above baseline of glyphs on current line */
- static long max_down; /* max depth below baseline of glyphs on cur line */
- static long min_x; /* left horizontal offset of cur. line */
- static long max_x; /* rightmost position on current line */
-
- #ifdef NOALLOC
- char* vpalloc(i, k)
- int i, k;
- {
- int j;
- static char c;
-
- j = i;
- j = k;
- return(&c);
- }
- #else
- #define vpalloc calloc
- #endif
-
- vf_init(quality, ff)
- int quality;
- char* ff;
- {
- int i, j;
- u_char huge* vp;
-
- fontFamily = ff;
- new_page = TRUE;
- for (i = 0; i < NLINES; i++)
- for (j = 0, vp = raster[i]; j < RASTWIDTH; j++)
- *vp++ = 0;
- if (quality == 2)
- {
- gl_dpi = dpi = 150;
- fprintf(outFile, "\033*r1Q");
- } else
- fprintf(outFile, "\033*r0Q");
- cfnum = -1;
- for (i=0; i < MAX_FONT; i++)
- {
- fontcache[i].fnum = -1;
- if ((fontcache[i].dsp = (struct dispatch *)
- vpalloc(NUM_DISPATCH, sizeof(struct dispatch))) == NULL)
- {
- fprintf(stderr, "malloc failed (A, %d)\n", i);
-
- exit(1);
- }
- if ((fontcache[i].image = (u_char *)
- vpalloc(IMG_SIZE, 1)) == NULL)
- {
- fprintf(stderr, "malloc failed (B, %d)\n", i);
- exit(1);
- }
- }
- }
-
- /*
- * loadfont -- load vfont
- *
- */
- loadfont(fnum, psize)
- int fnum, psize;
- {
- int i, c, sel;
-
- if (cfnum == fnum && cpsize == psize)
- return;
- for (i=0; i < MAX_FONT; i++)
- {
- if (fontcache[i].fnum == fnum && fontcache[i].psize == psize)
- {
- cfnum = fnum;
- cpsize = psize;
- cdsp = fontcache[i].dsp;
- imageTable = fontcache[i].image;
- fontcache[i].count = use_count++;
- return;
- }
- }
- /* not in cached set => load in place of LRU font */
- c = use_count;
- sel = -1;
- for (i=0; i < MAX_FONT; i++)
- {
- if (fontcache[i].count < c)
- {
- c = fontcache[i].count;
- sel = i;
- }
- }
- assert(sel != -1);
- getfont(fnum, psize, sel);
- /* recursively call loadfont to properly select the
- * font we've just loaded. i.e. retry loadfont operation
- */
- loadfont(fnum, psize);
- }
-
-
- getfont(fnum, psize, position)
- int fnum, psize, position;
- {
- static char fontBuf[BUFSIZ];
- int fd; /* file handle for vfont file */
- int i;
- unsigned int len;
-
- assert(fnum <= (strlen(FONTS)-1));
- #ifdef UNIX
- sprintf(fontBuf, "%s%c.%d", fontFamily, tolower(fpos[fnum]), psize);
- if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
- {
- sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
- if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
- {
- fprintf(stderr,
- "lcat: Could not load font %s\n", fontBuf);
- exit(1);
- }
- }
- #else
- sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
-
- if ((fd = open(fontBuf, O_BINARY|O_RDONLY)) < 0)
- {
- fprintf(stderr, "lcat: Could not load font %s\n", fontBuf);
- exit(1);
- }
- #endif
- DEBUGPRINTF(diagFile, "Loaded font %s (dpi: %d)\n", fontBuf, gl_dpi);
- fprintf(stderr, "Loaded font %s (dpi: %d)\n", fontBuf, gl_dpi);
- len = sizeof(struct header);
- if (read(fd, &vf_header, len) != len)
- {
- fprintf(stderr, "lcat: Bad font file header\n");
- exit(1);
- }
- if (vf_header.magic != VFONT_MAGIC)
- {
- fprintf(stderr, "lcat: Bad font magic number\n");
- exit(1);
- }
- len = NUM_DISPATCH*sizeof(struct dispatch);
- if (read(fd, fontcache[position].dsp, len) != len)
- {
- fprintf(stderr, "lcat: Could not load font dispatch table\n");
- exit(1);
- }
- len = vf_header.size;
- if (len > IMG_SIZE)
- {
- fprintf(stderr, "lcat: image table size (= %u) TOO BIG\n", len);
- exit(1);
- }
- if ((unsigned)read(fd, fontcache[position].image, len) != len)
- {
- fprintf(stderr, "lcat: Error reading image table\n");
- exit(1);
- }
- close(fd);
- fontcache[position].fnum = fnum;
- fontcache[position].psize = psize;
- return;
- }
-
- #define CAT_L '\004'
- #define CAT_I '\005'
- #define CAT_F '\013'
- #define CAT_FI '\0122'
- #define CAT_FL '\0123'
- #define CAT_FF '\0124'
- #define CAT_FFL '\0126'
- #define CAT_FFI '\0127'
-
- flashrast(ch, ps, ftype)
- int ch, ps, ftype;
- {
- int up, down, left, right;
- register int idx;
- register int i,j,H,V;
- u_char huge *bp;
- u_char huge *vp;
- int points;
- long x;
- long oxpos;
-
- points = (gl_dpi == 150) ? ps>>1: ps;
- if (ftype != cfnum || points != cpsize)
- loadfont(ftype, points);
-
- idx = (ftype==SPEC_FONT) ? spectab[ch] : asctab[ch];
- /*
- * composite glyphs ff, fi, fl, ffi, ffl get special treatment
- * since they are not available on all fonts.
- * If we don't have the glyph, we call flashrast recursivelly
- * until all but the last characters making up the composite
- * glyph have been printed. Then we continue executing
- * flashrast with the last character.
- */
- if (ftype != SPEC_FONT)
- switch (ch) {
- case CAT_FFI:
- if (cdsp[idx].nbytes > 0)
- break;
- flashrast(CAT_F, ps, ftype);
- idx = asctab[CAT_F];
- xpos += cdsp[idx].width;
- idx = asctab[CAT_FI];
- /* NOTE --> NO BREAK HERE */
- case CAT_FI:
- if (cdsp[idx].nbytes > 0)
- break;
- flashrast(CAT_F, ps, ftype);
- idx = asctab[CAT_F];
- xpos += cdsp[idx].width;
- idx = asctab[CAT_I];
- break;
- case CAT_FFL:
- if (cdsp[idx].nbytes > 0)
- break;
- flashrast(CAT_F, ps, ftype);
- idx = asctab[CAT_F];
- xpos += cdsp[idx].width;
- idx = asctab[CAT_FL];
- /* NOTE --> NO BREAK HERE */
- case CAT_FL:
- if (cdsp[idx].nbytes > 0)
- break;
- flashrast(CAT_F, ps, ftype);
- idx = asctab[CAT_F];
- xpos += cdsp[idx].width;
- idx = asctab[CAT_L];
- break;
- case CAT_FF:
- if (cdsp[idx].nbytes > 0)
- break;
- flashrast(CAT_F, ps, ftype);
- idx = asctab[CAT_F];
- xpos += cdsp[idx].width;
- break;
- }
- #ifdef VERBOSE
- if (idx >= ' ' && idx <= 126)
- putchar(idx);
- #endif VERBOSE
- up = cdsp[idx].up;
- down = cdsp[idx].down;
- left = cdsp[idx].left;
- right = cdsp[idx].right;
- V = up + down;
- H = (left + right + 7) / 8;
- bp = imageTable + cdsp[idx].addr;
- DEBUGPRINTF(diagFile, "ch=%d,fnt=%d,idx=%d,V=%d,H=%d\n", ch, ftype, idx, V, H);
- x = xpos + left + right;
- max_x = MAX(max_x, x);
- max_up = MAX(max_up, up);
- max_down = MAX(max_down, down);
- oxpos = xpos;
- xpos -= left;
- min_x = MIN(min_x, xpos);
- DEBUGPRINTF(diagFile, "y_base=%ld,min_x=%ld,max_x=%ld,max_up=%ld,max_down=%ld\n",
- y_base, min_x, max_x, max_up, max_down);
- vp=&raster[BASELINE - up][(int)(xpos >> 3)]; DEBUGPRINTF(diagFile, "\ttop of cell %lx\n", vp);
- DEBUGPRINTF(diagFile, "vp = %lx, xposMOD8= %d, xpos = %ld, V=%d, H=%d, bp=%lx\n", vp, (int)(xpos%8), xpos, V, H, bp);
- for (i = 0; i < V; i++, bp+=H)
- {
- vp = &raster[BASELINE - up + i][(int)(xpos >> 3)];
- bit_move(vp, (int)(xpos%8), bp, H);
- }
- xpos = oxpos;
- }
-
- /*
- * print_raster -- we print the raster from y_base-max_up to
- * y_base+max_down
- */
- print_raster()
- {
- long l_width; /* width of line in bytes */
- int i,j;
- u_char huge* vp;
- long lx, ly;
- #ifndef LASERJET
- #define MAX_REP_COUNT 128
- int count, offset;
- char c;
- #endif
-
- #ifdef VERBOSE
- putchar('\n');
- #endif VERBOSE
- lx = min_x*720L/dpi;
- ly = (y_base-max_up)*720L/dpi;
- fprintf(outFile, "\033&a%ldh%ldV", lx, ly);
- l_width = ((max_x - min_x + 7) / 8) + 1;
- DEBUGPRINTF(diagFile, "move(%ld, %ld), l_width=%ld\n", lx, ly, l_width);
- if (l_width >= RASTWIDTH)
- {
- fprintf(stderr, "print_raster: l_width(%ld) exceeds RASTWIDTH\n",
- l_width);
- exit(1);
- }
- fprintf(outFile, "\033*t%dR\033*r%ldS", dpi, l_width<<3);
- fprintf(outFile, "\033*r1A");
- for (i = BASELINE - max_up; i <= BASELINE + max_down; i++)
- {
- vp = &raster[i][min_x >> 3];
- DEBUGPRINTF(diagFile, "printing line %lx\n", vp);
- #ifdef LASERJET
- fprintf(outFile, "\033*b%ldW", l_width);
- fwrite((void *)vp, l_width, 1, outFile);
- #ifdef BSD
- bzero(vp, l_width);
- #else
- memset((void *)vp, '\0', l_width);
- #endif
- #else
- for (offset = 0; offset < l_width;)
- {
- for (count = 0, c = *vp;
- c == *vp && offset < l_width && count < MAX_REP_COUNT; offset++, count++)
- *vp++ = 0;
- if (count <= 1)
- push_buf(c);
- else {
- flush_buf();
- multiprint(c, count);
- }
- }
- flush_outbuf();
- #endif
- #ifdef XXX
- for (j = 0; j < l_width; j++)
- {
- putc(*vp, outFile);
- *vp++ = 0; /* ready raster for next pass */
- }
- #endif XXX
- }
- fprintf(outFile, "\033*rB");
- }
-
- vf_move(x, y)
- long x, y;
- {
- xpos = x * dpi/720;
- ypos = y * dpi/720;
-
- if (new_page || (y_base != ypos))
- {
- if (new_page)
- new_page = FALSE;
- else
- print_raster();
- y_base = ypos;
- max_up = max_down = 0;
- min_x = max_x = xpos;
- }
- }
-
- vf_newpage()
- {
- new_page = TRUE;
- print_raster();
- putc('\f', outFile);
- fflush(outFile);
- }
-
- prt(s, vp, nb, nl)
- char *s;
- u_char huge* vp;
- int nb, nl;
- {
- int i;
-
- DEBUGPRINTF(diagFile, "%s= ", s);
- for(i=0; i< nb; i++)
- DEBUGPRINTF(diagFile, "%2x, ", *vp++);
- if (nl)
- DEBUGPRINTF(diagFile, "%2x\n", *vp);
- else
- DEBUGPRINTF(diagFile, "%2x\t", *vp);
- }
-
- #ifndef LASERJET
- /*
- * routines used with the DeskJet graphics compression scheme
- */
- #define MAXBUF 400
- char out_buffer[MAXBUF];
- char *outbuf = out_buffer;
- int outoff = 0;
-
- flush_outbuf()
- {
- flush_buf();
- fprintf(outFile, "\033*b2m%dW", outoff);
- fwrite(out_buffer, outoff, 1, outFile);
- outbuf = out_buffer;
- outoff = 0;
- }
-
- #define PUSHBUFLEN MAX_REP_COUNT
- char pushbuf[PUSHBUFLEN];
- int pushoff = 0;
-
- push_buf(c)
- char c;
- {
- pushbuf[pushoff++] = c;
- if (pushoff >= PUSHBUFLEN)
- flush_buf();
- }
-
- multiprint(c, count)
- char c;
- int count;
- {
- *outbuf++ = -(count-1);
- *outbuf++ = c;
- outoff += 2;
- }
-
- flush_buf()
- {
- if (pushoff == 0)
- return;
- assert(outoff+pushoff+1 < MAXBUF);
- *outbuf++ = pushoff-1;
- #ifdef BSD
- bcopy(pushbuf, outbuf, pushoff);
- #else
- memcpy(outbuf, pushbuf, pushoff);
- #endif
- outbuf += pushoff;
- outoff += (pushoff + 1);
- pushoff = 0;
- }
- #endif /* !LASERJET */
-
-