home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char ScrId[] = "@(#) rf.c:1.3";
- #endif
-
- /*****************************************************************
-
- Copyright 1985. All Rights Reserved Chris Lewis
-
- Module : rf.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:
-
- vp@cui.unige.ch 19.2.90:
- modified to work with downloadble (soft) fonts. The program
- keeps a record of which fonts have been dent down so that only
- new fonts are downloaded.
-
- the size of the cache shoud be adjusted according to the
- memory available on the printer and the size of the fonts
- used.
-
- BUGS:
- - may work with MSDOS/TURBOC but then again it may not
- - the names of the downloaded fonts should be kept in
- a file so that subsequent programs know about them.
-
-
- ******************************************************************/
-
- #include <assert.h>
- #include <stdio.h>
- #include <fcntl.h>
- #ifdef UNIX
- #include <ctype.h>
- #include <vfont.h>
- #include <sys/file.h>
- #else
- #include <alloc.h>
- #include <mem.h>
- #include <vp/vfont.h>
- #endif
- #include "lcat.h"
-
- extern FILE *diagFile;
- extern FILE *outFile;
- #define DEBUGPRINTF if (diagFile) fprintf
- #define REGISTER /**/
- static char *fontFamily;
- static char *djfontFamily;
- #define FONTS "RIBS"
- char fpos[] = FONTS;
-
- extern char* ft_getname();
-
- #define STD_DPI 300
- static int dpi = STD_DPI;
- static int gl_dpi = STD_DPI;
-
- #define MAX_FONT 16
- #define SPEC_FONT 3
- #define IMG_SIZE (unsigned int)(50000)
-
- /*
- * Construction of font identifier (fid):
- * Since the fid is 15 bits wide, we can use it to encode information
- * about the font that will be loaded in that position.
- * +-+--------+------+-----------+
- * |X| Family | type | pointsize |
- * +-+--------+------+-----------+
- * bits |1| 6 | 3 | 6 |
- * +-+--------+------+-----------+
- * X: is the sign bit and cannot be used.
- * Family: is the font family and we use the same numbers as HP
- * uses for the typeface field in the font control block
- * (see page 5-10 of developers guide).
- * Type: 0=normal, 1=italic, 2=bold, 3=special
- * Pointsize:
- */
- #define FID_TIMES 5
- #define FID_HELVETICA 4
- #define FID_PRESTIGE 8
- #define FID_FAMO 9
- #define FID_FAMM 0x3f
- #define FID_TYPO 6
- #define FID_TYPM 0x7
- #define FID_PNTO 0
- #define FID_PNTM 0x3f
-
- static long xpos = -1;
- static long ypos = -1;
-
- struct ftbl {
- int fnum; /* number of downloaded font (R=0, I=1, B=2, S=3) */
- int psize; /* pointsize of font */
- int count; /* usage counter for LRU caching */
- int used; /* true if font appears on current page */
- int fid; /* only used by the MSDOS font cache */
- int lpad_tbl_valid; /* is left pad table valid? */
- int lpad_tbl[NUM_DISPATCH]; /* left pad table */
- } fonttbl[MAX_FONT];
-
- /*
- * following vars hold data for selected font
- */
- int cfnum, cpsize;
- int *clpad_tbl;
- struct dispatch *cdsp;
- u_char huge* imageTable;
- int use_count=1;
-
-
- #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 */
-
- vf_init(quality, ff, dj)
- int quality;
- char* ff;
- char* dj;
- {
- int i, j;
- u_char *vp;
-
- fontFamily = ff;
- #ifndef UNIX
- djfontFamily = dj;
- #endif
- new_page = TRUE;
- /* don't need that any more ...
- if (quality == 2)
- fprintf(outFile, "\033*r1Q");
- else
- fprintf(outFile, "\033*r0Q");
- */
- cfnum = -1;
- for (i=0; i < MAX_FONT; i++)
- {
- int fid;
-
- fonttbl[i].fnum = -1;
- fonttbl[i].count = -1;
- fonttbl[i].used = 0;
- fonttbl[i].fid = -1;
- fonttbl[i].lpad_tbl_valid = 0;
-
- if ((fid = ft_getnextent()) > 0)
- if (((fid >> FID_FAMO) & FID_FAMM) == FID_TIMES)
- {
- fonttbl[i].fnum = ((fid >> FID_TYPO) & FID_TYPM);
- fonttbl[i].psize = ((fid >> FID_PNTO) & FID_PNTM);
- fonttbl[i].fid = fid;
- fonttbl[i].count = 0;
- fonttbl[i].used = 0;
- }
- }
- }
-
- /*
- * 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 (fonttbl[i].fnum == fnum && fonttbl[i].psize == psize)
- {
- cfnum = fnum;
- cpsize = psize;
- clpad_tbl = fonttbl[i].lpad_tbl;
- if (!fonttbl[i].lpad_tbl_valid)
- if (!fonttbl[i].lpad_tbl_valid)
- {
- get_lpad_tbl(fnum, psize, clpad_tbl);
- fonttbl[i].lpad_tbl_valid = 1;
- }
- fonttbl[i].used = 1;
- fonttbl[i].count = use_count++;
- /* select it */
- #ifdef VERBOSE
- printf("Using font %s (%d)\n",
- ft_getname(fonttbl[i].fid), fonttbl[i].fid);
- #endif
- fprintf(outFile, "\033(%dX", fonttbl[i].fid);
- return;
- }
- }
- /* not in downloaded set => load in place of LRU font */
- c = use_count;
- sel = -1;
- for (i=0; i < MAX_FONT; i++)
- {
- if (fonttbl[i].used)
- continue;
- if (fonttbl[i].count < c)
- {
- c = fonttbl[i].count;
- sel = i;
- }
- }
- assert(sel != -1);
-
- /* delete font from printer */
- if (fonttbl[sel].fid != -1)
- {
- fprintf(outFile, "\033*c%D\033*c2D", fonttbl[sel].fid);
- /* delete font from cache table, doesn't matter if its not there */
- printf("deleting font %d\n", fonttbl[sel].fid);
- ft_delent(fonttbl[sel].fid);
- }
- 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 --
- */
- getfont(fnum, psize, position)
- int fnum, psize, position;
- {
- static char fontBuf[BUFSIZ];
- #ifdef UNIX
- static char sbuf[BUFSIZ];
- #endif
- int fd; /* file handle for vfont file */
- int i;
- int xx, c;
- FILE* font_fd;
- int fid;
-
- assert(fnum <= (strlen(FONTS)-1));
- fid = (FID_TIMES & FID_FAMM) << FID_FAMO;
- fid |= ((fnum & FID_TYPM) << FID_TYPO);
- fid |= ((psize & FID_PNTM) << FID_PNTO);
- #ifdef UNIX
- sprintf(fontBuf, "%s%c.%d", fontFamily, tolower(fpos[fnum]), psize);
- if (access(fontBuf, R_OK) < 0)
- {
- sprintf(fontBuf, "%s%c.%d", fontFamily, fpos[fnum], psize);
- if (access(fontBuf, R_OK) < 0)
- {
- fprintf(stderr,
- "lcat: Could not load font %s\n", fontBuf);
- exit(1);
- }
- }
- sprintf(sbuf, "./railmag -s %d0%c -i %d %s",
- psize, fpos[fnum], fid, fontBuf);
- /* fprintf(stderr, "calling %s\n", sbuf); */
- if ((xx = system(sbuf)) != 0)
- {
- fprintf(stderr, "lcat: railmag reported an error (%x)\n", xx);
- exit(1);
- }
- #else
- /* Unfortunately MSDOS systems cannot accomodate both
- * programs; instead we have to prepare the DeskJet files in
- * advance, so that here we only need to copy the data
- * to the printer.
- */
- sprintf(fontBuf, "%s%c.%d", djfontFamily, fpos[fnum], psize);
- if ((font_fd = fopen(fontBuf, "rb")) == NULL)
- {
- fprintf(stderr, "lcat: Could not load font %s\n", fontBuf);
- exit(1);
- }
- /* specify font number */
- fprintf(stderr, "Downloading font %s, fid %d\n", fontBuf, fid);
- fprintf(outFile,"\033*c%dD", fid);
- while ((c = getc(font_fd)) != EOF)
- putc(c, outFile);
- fclose(font_fd);
- /* select font and make it permanent */
- fprintf(outFile,"\033*c5F\033(%dX", fid);
- #endif
-
- fonttbl[position].fnum = fnum;
- fonttbl[position].psize = psize;
- /* update font table */
- fonttbl[position].fid = fid;
- ft_addent(fid, fontBuf);
- return;
- }
-
- /*
- * get_lpad_tbl -- get the left pad bytes for given font
- */
-
- get_lpad_tbl(fnum, psize, tbl)
- int fnum, psize;
- int *tbl;
- {
- static char fontBuf[BUFSIZ];
- static struct dispatch dsptbl[NUM_DISPATCH];
- static struct header vf_header;
- int fd; /* file handle for vfont file */
- int i;
- unsigned int len;
-
- #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
- fprintf(stderr, "\tLoaded description for %s\n", fontBuf);
- 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, dsptbl, len) != len)
- {
- fprintf(stderr, "lcat: Could not load font dispatch table\n");
- exit(1);
- }
- close(fd);
-
- /* tranfer left pads to left pad table */
- for (i=0; i < NUM_DISPATCH; i++)
- tbl[i] = dsptbl[i].left;
- return;
- }
-
- #define VF_FI '\01'
- #define VF_FL '\02'
- #define VF_FF '\03'
- #define VF_FFL '\012'
- #define VF_FFI '\011'
-
- flashrast(ch, ps, ftype)
- int ch, ps, ftype;
- {
- int up, down, left, right;
- char idx;
- register int i,j,H,V;
- u_char huge *bp;
- u_char huge *vp;
- int points;
- long axpos; /* adjusted xpos (by lpad) */
- long x;
-
- points = (gl_dpi == 150) ? ps>>1: ps;
- if (ftype != cfnum || points != cpsize)
- loadfont(ftype, points);
- idx = (char)((ftype==SPEC_FONT) ? spectab[ch] : asctab[ch]);
- if (clpad_tbl[idx] > 0)
- axpos = xpos - (clpad_tbl[idx] * 2);
- else
- axpos = xpos;
- #ifdef USELIGATURES
- /* Unfortunately the code for ligatures doesn't work!
- * Since we have to adjust the spacing of the characters
- * we cannot just send a string (e.g. ffi) to the printer,
- * the spacing will be all wrong. Also if a font doesn't have
- * ligatures, then the clpad[idx] will be zero, we would have
- * to use the lpad of 'f'. What I am trying to say that its too
- * much of a bother to implement when you can just ask troff
- * not to generate ligatures (.lg 0).
- */
- /*
- * composite glyphs ff, fi, fl, ffi, ffl get special treatment
- * since they are not available on all fonts.
- */
- /*
- fprintf(stderr, "ftype %d, ch %o\n", ftype, idx);
- */
- if (ftype != SPEC_FONT)
- switch (idx) {
- case VF_FFI:
- fprintf(outFile, "\033&a%ldh%ldVffi", axpos, ypos);
- return;
- case VF_FI:
- fprintf(outFile, "\033&a%ldh%ldVfi", axpos, ypos);
- return;
- case VF_FFL:
- fprintf(outFile, "\033&a%ldh%ldVffl", axpos, ypos);
- return;
- case VF_FL:
- fprintf(outFile, "\033&a%ldh%ldVfl", axpos, ypos);
- return;
- case VF_FF:
- fprintf(outFile, "\033&a%ldh%ldVff", axpos, ypos);
- return;
- }
- #endif
- /* if the character is in the unprintable region, escape it */
- if (((idx & 0x7f) < 32) || ((idx & 0x7f) == 0x7f))
- fprintf(outFile, "\033&a%ldh%ldV\033&p1X%c", axpos, ypos, idx);
- else
- fprintf(outFile, "\033&a%ldh%ldV%c", axpos, ypos, idx);
- }
-
- vf_move(x, y)
- long x, y;
- {
- xpos = x;
- ypos = y;
- if (new_page)
- new_page = FALSE;
- }
-
- vf_newpage()
- {
- int i;
-
- new_page = TRUE;
- /* mark all fonts as unused */
- for (i=0; i < MAX_FONT; i++)
- {
- fonttbl[i].used = 0;
- }
- /* eject page */
- putc('\f', 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);
- }
-
-