1*25330Sslatteng /* dip.c 1.12 (Berkeley) 85/10/29
214396Sslatteng * dip
314396Sslatteng * driver for impress/imagen canon laser printer
414396Sslatteng */
514396Sslatteng
614396Sslatteng /*
714396Sslatteng output language from troff:
814396Sslatteng all numbers are character strings
914396Sslatteng
1014396Sslatteng sn size in points
1114396Sslatteng fn font as number from 1-n
1216406Sslatteng in stipple `font' as number from 1-n
1314396Sslatteng cx ascii character x
1414396Sslatteng Cxyz funny char xyz. terminated by white space
1514396Sslatteng Hn go to absolute horizontal position n
1614396Sslatteng Vn go to absolute vertical position n (down is positive)
1714396Sslatteng hn go n units horizontally (relative)
1814396Sslatteng vn ditto vertically
1914396Sslatteng nnc move right nn, then print c (exactly 2 digits!)
2014396Sslatteng (this wart is an optimization that shrinks output file size
2114396Sslatteng about 35% and run-time about 15% while preserving ascii-ness)
2214396Sslatteng Dt ...\n draw operation 't':
2316406Sslatteng Dt d line thickness set to d
2416406Sslatteng Ds d line style (coordinate bit map) set to d
2514396Sslatteng Dl x y line from here by x,y
2614396Sslatteng Dc d circle of diameter d with left side here
2714396Sslatteng De x y ellipse of axes x,y with left side here
2814396Sslatteng Da x y r arc counter-clockwise by x,y of radius r
2914396Sslatteng D~ x y x y ... wiggly line by x,y then x,y ...
3016406Sslatteng Dg x y x y ... gremlin spline by x,y then x,y ...
3116406Sslatteng Dp s x y ... polygon filled with s by x,y then ...
3216503Sslatteng DP s x y ... unbordered polygon filled with s by x,y then ...
3314396Sslatteng nb a end of line (information only -- no action needed)
3414396Sslatteng b = space before line, a = after
3514967Sslatteng pn new page begins -- set v to 0
3614396Sslatteng #...\n comment
3714396Sslatteng x ...\n device control functions:
3814396Sslatteng x i init
3914396Sslatteng x T s name of device is s
4014396Sslatteng x r n h v resolution is n/inch
4114396Sslatteng h = min horizontal motion, v = min vert
4214396Sslatteng x p pause (can restart)
4314396Sslatteng x s stop -- done for ever
4414396Sslatteng x t generate trailer
4514396Sslatteng x f n s font position n contains font s
4614396Sslatteng x H n set character height to n
4714396Sslatteng x S n set slant to N
4814396Sslatteng
4914396Sslatteng Subcommands like "i" are often spelled out like "init".
5014396Sslatteng */
5114396Sslatteng
5214396Sslatteng #include <stdio.h>
5314396Sslatteng #include <signal.h>
5414396Sslatteng #include <math.h>
5514396Sslatteng #include <ctype.h>
5614396Sslatteng #include "dev.h"
5714396Sslatteng #include "canon.h"
5814967Sslatteng #include "rst.h"
5914396Sslatteng
6014396Sslatteng
6114967Sslatteng /* #define DEBUGABLE /* whether or not it'll accept the -d option */
6214967Sslatteng #define abs(n) ((n) >= 0 ? (n) : -(n))
6314967Sslatteng #define hmot(n) hpos += n
6414967Sslatteng #define hgoto(n) hpos = n
6514967Sslatteng #define vmot(n) vpos += n
6614967Sslatteng #define vgoto(n) vpos = n
6714396Sslatteng
6814967Sslatteng #define FATAL 1
6914967Sslatteng #define BMASK 0377
7016406Sslatteng #define NFONT 35 /* maximum forever */
7114396Sslatteng
7215736Sslatteng #ifndef FONTDIR
7314967Sslatteng #define FONTDIR "/usr/lib/font";
7415736Sslatteng #endif
7514967Sslatteng #define BITDIR "/usr/local/lib/ifontt";
7614967Sslatteng
7714967Sslatteng /* BOTTOMTHRESH and DELTATHRESH are used to */
7814967Sslatteng /* search through the glyphs downloaded to */
7914967Sslatteng /* determine which ones to keep and which to */
8014967Sslatteng /* dump. They're tested against BOTTOMTHRESH */
8114967Sslatteng /* first, then if THAT doesn't release enough */
8214967Sslatteng /* space, DELTATHRESH is added until it is. */
8314967Sslatteng #define BOTTOMTHRESH 16
8414967Sslatteng #define DELTATHRESH 16
8514967Sslatteng #define MEMSIZE 70000 /* amount of memory inside imagen */
8614967Sslatteng #define BUFFER 20000 /* imagen memory set aside for page buffer */
8714967Sslatteng #define CHARRAY 128 /* size of character use count array */
8814967Sslatteng
8914967Sslatteng int MAXX = (RES*8+RES/3); /* size of the page... (not 8-1/2" x 11", */
9014967Sslatteng int MAXY = (RES*10+RES/2+RES/4); /* but 8-1/3" x 10-3/4") */
9114967Sslatteng
9214967Sslatteng int output = 0; /* do we do output at all? */
9314967Sslatteng int pageno = -1; /* output page number */
9414967Sslatteng int nolist = 0; /* output page list if > 0 */
9514967Sslatteng int olist[20]; /* pairs of page numbers */
9614967Sslatteng
9714396Sslatteng struct dev dev;
9814396Sslatteng struct font *fontbase[NFONT+1];
9914967Sslatteng short * pstab;
10014967Sslatteng int nsizes = 1;
10114396Sslatteng int nfonts;
10216406Sslatteng int nstips;
10314396Sslatteng int nchtab;
10414967Sslatteng char * chname;
10514967Sslatteng short * chtab;
10614967Sslatteng unsigned char * fitab[NFONT+1]; /* legal characters for each font */
10714967Sslatteng unsigned char * widtab[NFONT+1]; /* width table for each font */
10814967Sslatteng unsigned char * codetab[NFONT+1]; /* device code translation */
10914967Sslatteng char * fontname[NFONT+1]; /* what font is on what position? */
11014396Sslatteng
11114967Sslatteng #ifdef DEBUGABLE
11214396Sslatteng int dbg = 0;
11314967Sslatteng #endif
11414396Sslatteng
11514967Sslatteng FILE * tf = stdout; /* output file pointer */
11614967Sslatteng char * fontdir = FONTDIR;
11714967Sslatteng char * bitdir = BITDIR;
11814967Sslatteng FILE * fp = stdin; /* input file pointer */
11914396Sslatteng
12014967Sslatteng int totglyph= 0; /* total space used by glyphs sent down */
12114967Sslatteng int maxglyph= MEMSIZE - BUFFER; /* maximum space for glyphs */
12214967Sslatteng
12314967Sslatteng int size = 1;
12414967Sslatteng int font = 1;
12516406Sslatteng int stip = 1;
12614967Sslatteng int family;
12714967Sslatteng int hpos; /* current horizontal position (left = 0) */
12814967Sslatteng int vpos; /* current vertical position (down positive) */
12914967Sslatteng int lastw = 0; /* width of last input character */
13016503Sslatteng extern int polyborder; /* flag to turn off borders around a polygon */
13114967Sslatteng
13214967Sslatteng typedef struct {
13314967Sslatteng int font;
13414967Sslatteng int size;
13516406Sslatteng short first;
13616406Sslatteng short last;
13714967Sslatteng unsigned char chused[CHARRAY]; /* test array - character downloaded? */
13814967Sslatteng glyph_dir *glyph; /* array of character descriptions */
13914967Sslatteng unsigned char *cdp; /* char data pointer */
14014967Sslatteng } fontset;
14114967Sslatteng
14214967Sslatteng fontset *fs; /* A global pointer to the current family */
14314967Sslatteng fontset fontdata[NFONT+1]; /* table of family data descripters */
14414967Sslatteng
14514967Sslatteng int lastsize = -1;
14614967Sslatteng int lastfont = -1;
14714967Sslatteng int lastx = -1;
14814967Sslatteng int lasty = -1;
14914967Sslatteng int lastfam = -1;
15016406Sslatteng int laststip = -1;
15116406Sslatteng int laststipmem = -1;
15214967Sslatteng
15314967Sslatteng
15414967Sslatteng
main(argc,argv)15514396Sslatteng main(argc, argv)
15614396Sslatteng char *argv[];
15714396Sslatteng {
15814967Sslatteng int i;
15914396Sslatteng char *mktemp();
16014967Sslatteng char *operand();
16114396Sslatteng
16214967Sslatteng while (--argc > 0 && **++argv == '-') {
16314967Sslatteng switch ((*argv)[1]) {
16415278Sslatteng case 'X':
16515278Sslatteng MAXX = atoi(operand(&argc, &argv));
16615278Sslatteng break;
16715278Sslatteng case 'Y':
16815278Sslatteng MAXY = atoi(operand(&argc, &argv));
16915278Sslatteng break;
17014967Sslatteng case 'F':
17114967Sslatteng fontdir = operand(&argc, &argv);
17214396Sslatteng break;
17314396Sslatteng case 'f':
17414967Sslatteng bitdir = operand(&argc, &argv);
17514396Sslatteng break;
17614396Sslatteng case 'o':
17714967Sslatteng outlist(operand(&argc, &argv));
17814396Sslatteng break;
17914396Sslatteng case 'b':
18014967Sslatteng if ((i = atoi(operand(&argc, &argv))) < 1000) i = 1000;
18114967Sslatteng else if (i > MEMSIZE - 1000) i = MEMSIZE - 1000;
18214967Sslatteng maxglyph = MEMSIZE - i;
18314396Sslatteng break;
18414967Sslatteng #ifdef DEBUGABLE
18514396Sslatteng case 'd':
18614967Sslatteng dbg = atoi(operand(&argc, &argv));
18714967Sslatteng if (dbg == 0) error (FATAL, "no debug value");
18814396Sslatteng break;
18914967Sslatteng #endif
19014396Sslatteng }
19114396Sslatteng }
19214396Sslatteng
19314967Sslatteng if (argc < 1)
19414396Sslatteng conv(stdin);
19514396Sslatteng else
19614967Sslatteng while (argc-- > 0) {
19714967Sslatteng if (strcmp(*argv, "-") == 0)
19814396Sslatteng fp = stdin;
19914396Sslatteng else if ((fp = fopen(*argv, "r")) == NULL)
20014396Sslatteng error(FATAL, "can't open %s", *argv);
20114396Sslatteng conv(fp);
20214396Sslatteng fclose(fp);
20314967Sslatteng argv++;
20414396Sslatteng }
20514967Sslatteng
20614396Sslatteng t_wrapup();
20714967Sslatteng exit(0);
20814967Sslatteng }
20914967Sslatteng
21014967Sslatteng
21114967Sslatteng /*----------------------------------------------------------------------------*
21214967Sslatteng | Routine: char * operand (& argc, & argv)
21314967Sslatteng |
21414967Sslatteng | Results: returns address of the operand given with a command-line
21514967Sslatteng | option. It uses either "-Xoperand" or "-X operand", whichever
21614967Sslatteng | is present. The program is terminated if no option is present.
21714967Sslatteng |
21814967Sslatteng | Side Efct: argc and argv are updated as necessary.
21914967Sslatteng *----------------------------------------------------------------------------*/
22014967Sslatteng
operand(argcp,argvp)22114967Sslatteng char *operand(argcp, argvp)
22214967Sslatteng int * argcp;
22314967Sslatteng char ***argvp;
22414967Sslatteng {
22514967Sslatteng if ((**argvp)[2]) return(**argvp + 2); /* operand immediately follows */
22614967Sslatteng if ((--*argcp) <= 0) { /* no operand */
22715278Sslatteng error (FATAL, "command-line option operand missing.");
22814396Sslatteng }
22914967Sslatteng return(*(++(*argvp))); /* operand next word */
23014396Sslatteng }
23114396Sslatteng
23214967Sslatteng
outlist(s)23314396Sslatteng outlist(s) /* process list of page numbers to be printed */
23415617Sslatteng register char *s;
23514396Sslatteng {
23615617Sslatteng register int n1, n2;
23714396Sslatteng
23814396Sslatteng nolist = 0;
23914396Sslatteng while (*s) {
24014396Sslatteng n1 = 0;
24114396Sslatteng if (isdigit(*s))
24214396Sslatteng do
24314396Sslatteng n1 = 10 * n1 + *s++ - '0';
24414396Sslatteng while (isdigit(*s));
24514396Sslatteng else
24614396Sslatteng n1 = -9999;
24714396Sslatteng n2 = n1;
24814396Sslatteng if (*s == '-') {
24914396Sslatteng s++;
25014396Sslatteng n2 = 0;
25114396Sslatteng if (isdigit(*s))
25214396Sslatteng do
25314396Sslatteng n2 = 10 * n2 + *s++ - '0';
25414396Sslatteng while (isdigit(*s));
25514396Sslatteng else
25614396Sslatteng n2 = 9999;
25714396Sslatteng }
25814396Sslatteng olist[nolist++] = n1;
25914396Sslatteng olist[nolist++] = n2;
26014396Sslatteng if (*s != '\0')
26114396Sslatteng s++;
26214396Sslatteng }
26314396Sslatteng olist[nolist] = 0;
26414967Sslatteng #ifdef DEBUGABLE
26514396Sslatteng if (dbg)
26614396Sslatteng for (i=0; i<nolist; i += 2)
26714396Sslatteng printf("%3d %3d\n", olist[i], olist[i+1]);
26814967Sslatteng #endif
26914396Sslatteng }
27014396Sslatteng
27114967Sslatteng
in_olist(n)27214396Sslatteng in_olist(n) /* is n in olist? */
27314396Sslatteng int n;
27414396Sslatteng {
27514396Sslatteng int i;
27614396Sslatteng
27714396Sslatteng if (nolist == 0)
27814396Sslatteng return(1); /* everything is included */
27914396Sslatteng for (i = 0; i < nolist; i += 2)
28014396Sslatteng if (n >= olist[i] && n <= olist[i+1])
28114396Sslatteng return(1);
28214396Sslatteng return(0);
28314396Sslatteng }
28414396Sslatteng
28514967Sslatteng
conv(fp)28614396Sslatteng conv(fp)
28714396Sslatteng register FILE *fp;
28814396Sslatteng {
28914967Sslatteng register int c;
29014967Sslatteng register int k;
29114967Sslatteng int m, n, n1, m1;
29214396Sslatteng char str[100], buf[300];
29314396Sslatteng
29414396Sslatteng while ((c = getc(fp)) != EOF) {
29514396Sslatteng switch (c) {
29614396Sslatteng case '\n': /* when input is text */
29714396Sslatteng case ' ':
29814396Sslatteng case 0: /* occasional noise creeps in */
29914396Sslatteng break;
30014396Sslatteng case '0': case '1': case '2': case '3': case '4':
30114396Sslatteng case '5': case '6': case '7': case '8': case '9':
30214396Sslatteng /* two motion digits plus a character */
30314396Sslatteng hmot((c-'0')*10 + getc(fp)-'0');
30414396Sslatteng put1(getc(fp));
30514396Sslatteng break;
30614396Sslatteng case 'c': /* single ascii character */
30714396Sslatteng put1(getc(fp));
30814396Sslatteng break;
30914396Sslatteng case 'C':
31014396Sslatteng fscanf(fp, "%s", str);
31114396Sslatteng put1s(str);
31214396Sslatteng break;
31314396Sslatteng case 'D': /* draw function */
31416184Sslatteng if (fgets(buf, sizeof(buf), fp) == NULL)
31516184Sslatteng error(FATAL, "unexpected end of input");
31614396Sslatteng switch (buf[0]) {
31714396Sslatteng case 'l': /* draw a line */
31814396Sslatteng sscanf(buf+1, "%d %d", &n, &m);
31914967Sslatteng drawline(n, m, ".");
32014396Sslatteng break;
32114396Sslatteng case 'c': /* circle */
32214396Sslatteng sscanf(buf+1, "%d", &n);
32314396Sslatteng drawcirc(n);
32414396Sslatteng break;
32514396Sslatteng case 'e': /* ellipse */
32614396Sslatteng sscanf(buf+1, "%d %d", &m, &n);
32714396Sslatteng drawellip(m, n);
32814396Sslatteng break;
32914396Sslatteng case 'a': /* arc */
33014396Sslatteng sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
33114396Sslatteng drawarc(n, m, n1, m1);
33214396Sslatteng break;
33316503Sslatteng case 'P':
33416503Sslatteng polyborder = 0; /* borderless polygon */
33516406Sslatteng case 'p': /* polygon */
33616406Sslatteng sscanf(buf+1, "%d", &m);/* get stipple */
33716406Sslatteng n = 1; /* number first */
33816406Sslatteng while (buf[++n] == ' ');
33916406Sslatteng while (isdigit(buf[n])) n++;
34016406Sslatteng setfill(m); /* set up stipple */
34116406Sslatteng drawwig(buf+n, fp, -1); /* draw polygon */
34216503Sslatteng polyborder = 1; /* assume polygons */
34316503Sslatteng break; /* all have borders */
34416503Sslatteng
34514396Sslatteng case 'g': /* gremlin curve */
34615617Sslatteng drawwig(buf+1, fp, 0);
34715617Sslatteng break;
34814396Sslatteng case '~': /* wiggly line */
34915617Sslatteng drawwig(buf+1, fp, 1);
35014967Sslatteng break;
35115617Sslatteng case 't': /* line-thickness */
35214967Sslatteng sscanf(buf+1, "%d", &n);
35314967Sslatteng drawthick(n);
35414967Sslatteng break;
35515617Sslatteng case 's': /* line-style */
35614967Sslatteng sscanf(buf+1, "%d", &n);
35714967Sslatteng drawstyle(n);
35814396Sslatteng break;
35914396Sslatteng default:
36014967Sslatteng error(FATAL, "unknown drawing function %s",buf);
36114396Sslatteng break;
36214396Sslatteng }
36314396Sslatteng break;
36414396Sslatteng case 's':
36514396Sslatteng fscanf(fp, "%d", &n); /* ignore fractional sizes */
36614396Sslatteng setsize(t_size(n));
36714396Sslatteng break;
36814396Sslatteng case 'f':
36914396Sslatteng fscanf(fp, "%s", str);
37014396Sslatteng setfont(t_font(str));
37114396Sslatteng break;
37216406Sslatteng case 'i':
37316406Sslatteng fscanf(fp, "%d", &n);
37416406Sslatteng setstip(n);
37516406Sslatteng break;
37614396Sslatteng case 'H': /* absolute horizontal motion */
37714396Sslatteng /* fscanf(fp, "%d", &n); */
37814396Sslatteng while ((c = getc(fp)) == ' ')
37914396Sslatteng ;
38014396Sslatteng k = 0;
38114396Sslatteng do {
38214396Sslatteng k = 10 * k + c - '0';
38314396Sslatteng } while (isdigit(c = getc(fp)));
38414396Sslatteng ungetc(c, fp);
38514396Sslatteng hgoto(k);
38614396Sslatteng break;
38714396Sslatteng case 'h': /* relative horizontal motion */
38814396Sslatteng /* fscanf(fp, "%d", &n); */
38914396Sslatteng while ((c = getc(fp)) == ' ')
39014396Sslatteng ;
39114396Sslatteng k = 0;
39214396Sslatteng do {
39314396Sslatteng k = 10 * k + c - '0';
39414396Sslatteng } while (isdigit(c = getc(fp)));
39514396Sslatteng ungetc(c, fp);
39614396Sslatteng hmot(k);
39714396Sslatteng break;
39814396Sslatteng case 'w': /* word space */
39914396Sslatteng break;
40014396Sslatteng case 'V':
40114396Sslatteng fscanf(fp, "%d", &n);
40214396Sslatteng vgoto(n);
40314396Sslatteng break;
40414396Sslatteng case 'v':
40514396Sslatteng fscanf(fp, "%d", &n);
40614396Sslatteng vmot(n);
40714396Sslatteng break;
40814396Sslatteng case 'p': /* new page */
40914396Sslatteng fscanf(fp, "%d", &n);
41014396Sslatteng t_page(n);
41114396Sslatteng break;
41214396Sslatteng case 'n': /* end of line */
41314967Sslatteng hpos = 0;
41416184Sslatteng
41514396Sslatteng case '#': /* comment */
41616184Sslatteng do
41716184Sslatteng c = getc(fp);
41816184Sslatteng while (c != '\n' && c != EOF);
41914396Sslatteng break;
42014396Sslatteng case 'x': /* device control */
42115617Sslatteng if (devcntrl(fp)) return;
42214396Sslatteng break;
42314396Sslatteng default:
42415278Sslatteng error(FATAL, "unknown input character %o %c", c, c);
42514396Sslatteng }
42614396Sslatteng }
42714396Sslatteng }
42814396Sslatteng
42914967Sslatteng
devcntrl(fp)43015617Sslatteng int devcntrl(fp) /* interpret device control functions */
43115617Sslatteng FILE *fp; /* returns -1 upon "stop" command */
43214396Sslatteng {
43314396Sslatteng char str[20], str1[50], buf[50];
43414396Sslatteng int c, n;
43514396Sslatteng
43614396Sslatteng fscanf(fp, "%s", str);
43714396Sslatteng switch (str[0]) { /* crude for now */
43814396Sslatteng case 'i': /* initialize */
43914396Sslatteng fileinit();
44016406Sslatteng t_init();
44114396Sslatteng break;
44214396Sslatteng case 'T': /* device name */
44314396Sslatteng case 't': /* trailer */
44414396Sslatteng case 'p': /* pause -- can restart */
44515617Sslatteng break;
44614396Sslatteng case 's': /* stop */
44715617Sslatteng return -1;
44814396Sslatteng case 'r': /* resolution assumed when prepared */
44914967Sslatteng fscanf(fp, "%d", &n);
45016503Sslatteng if (n!=RES) error(FATAL,"Input computed for wrong printer");
45114396Sslatteng break;
45214396Sslatteng case 'f': /* font used */
45314396Sslatteng fscanf(fp, "%d %s", &n, str);
45414396Sslatteng fgets(buf, sizeof buf, fp); /* in case there's a filename */
45514396Sslatteng ungetc('\n', fp); /* fgets goes too far */
45614396Sslatteng str1[0] = 0; /* in case there's nothing to come in */
45714396Sslatteng sscanf(buf, "%s", str1);
45814396Sslatteng loadfont(n, str, str1);
45914396Sslatteng break;
46014396Sslatteng case 'H': /* char height */
46114396Sslatteng fscanf(fp, "%d", &n);
46214396Sslatteng t_charht(n);
46314396Sslatteng break;
46414396Sslatteng case 'S': /* slant */
46514396Sslatteng fscanf(fp, "%d", &n);
46614396Sslatteng t_slant(n);
46714396Sslatteng break;
46814396Sslatteng }
46914396Sslatteng while ((c = getc(fp)) != '\n') /* skip rest of input line */
47014396Sslatteng if (c == EOF)
47115617Sslatteng return -1;
47215617Sslatteng return 0;
47314396Sslatteng }
47414396Sslatteng
47514967Sslatteng
fileinit()47614396Sslatteng fileinit() /* read in font and code files, etc. */
47714396Sslatteng {
47814967Sslatteng register int i;
47914967Sslatteng register int fin;
48014967Sslatteng register int nw;
48114967Sslatteng register unsigned char *filebase;
48214967Sslatteng register unsigned char *p;
48314967Sslatteng unsigned char *malloc();
48414967Sslatteng char temp[100];
48514396Sslatteng
48614967Sslatteng /* open table for device,
48714967Sslatteng * read in resolution, size info, font info, etc.
48814967Sslatteng * and set params
48914967Sslatteng */
49014396Sslatteng
49114967Sslatteng sprintf(temp, "%s/devip/DESC.out", fontdir);
49214396Sslatteng if ((fin = open(temp, 0)) < 0)
49314396Sslatteng error(FATAL, "can't open tables for %s", temp);
49414396Sslatteng read(fin, &dev, sizeof(struct dev));
49514396Sslatteng nfonts = dev.nfonts;
49616406Sslatteng nstips = dev.nstips;
49714396Sslatteng nsizes = dev.nsizes;
49814396Sslatteng nchtab = dev.nchtab;
49914396Sslatteng filebase = malloc(dev.filesize); /* enough room for whole file */
50014396Sslatteng read(fin, filebase, dev.filesize); /* all at once */
50114396Sslatteng pstab = (short *) filebase;
50214396Sslatteng chtab = pstab + nsizes + 1;
50314396Sslatteng chname = (char *) (chtab + dev.nchtab);
50414967Sslatteng p = (unsigned char *) chname + dev.lchname;
50514967Sslatteng for (i = 1; i <= nfonts; i++) {
50614967Sslatteng fontbase[i] = (struct font *) p;
50714967Sslatteng nw = *p & BMASK; /* 1st thing is width count */
50814967Sslatteng p += sizeof(struct font);
50914967Sslatteng widtab[i] = p; /* then width table */
51014967Sslatteng codetab[i] = p + 2 * nw; /* then code conversion table */
51114967Sslatteng fitab[i] = p + 3 * nw; /* then font inclusion table */
51214967Sslatteng p += 3 * nw + dev.nchtab + 128 - 32;
51314967Sslatteng t_fp(i, fontbase[i]->namefont, fontbase[i]->intname);
51414967Sslatteng #ifdef DEBUGABLE
51514967Sslatteng if (dbg > 1) fontprint(i);
51614967Sslatteng #endif
51714396Sslatteng }
51816406Sslatteng for (i = 1; i <= nstips; i++) { /* add in Stipple "filenames" */
51916406Sslatteng if (nfonts + i <= NFONT)
52016406Sslatteng t_fp(nfonts + i, p, (char *)0);
52116406Sslatteng p += strlen(p) + 1;
52216406Sslatteng }
52314967Sslatteng fontbase[0] = NULL;
52414967Sslatteng close(fin); /* no fonts loaded yet */
52514967Sslatteng for (i = 0; i <= NFONT; i++) fontdata[i].font = fontdata[i].size = -1;
52614396Sslatteng }
52714396Sslatteng
52814967Sslatteng
52914967Sslatteng #ifdef DEBUGABLE
fontprint(i)53014396Sslatteng fontprint(i) /* debugging print of font i (0,...) */
53114396Sslatteng {
53214967Sslatteng int j, n;
53314396Sslatteng char *p;
53414396Sslatteng
53514396Sslatteng printf("font %d:\n", i);
53614396Sslatteng p = (char *) fontbase[i];
53714396Sslatteng n = fontbase[i]->nwfont & BMASK;
53814396Sslatteng printf("base=0%o, nchars=%d, spec=%d, name=%s, widtab=0%o, fitab=0%o\n",
53914967Sslatteng p, n, fontbase[i]->specfont, fontbase[i]->namefont, widtab[i], fitab[i]);
54014396Sslatteng printf("widths:\n");
54114396Sslatteng for (j=0; j <= n; j++) {
54214967Sslatteng printf(" %2d", widtab[i][j] & BMASK);
54314396Sslatteng if (j % 20 == 19) printf("\n");
54414396Sslatteng }
54514396Sslatteng printf("\ncodetab:\n");
54614396Sslatteng for (j=0; j <= n; j++) {
54714396Sslatteng printf(" %2d", codetab[i][j] & BMASK);
54814396Sslatteng if (j % 20 == 19) printf("\n");
54914396Sslatteng }
55014396Sslatteng printf("\nfitab:\n");
55114396Sslatteng for (j=0; j <= dev.nchtab + 128-32; j++) {
55214396Sslatteng printf(" %2d", fitab[i][j] & BMASK);
55314396Sslatteng if (j % 20 == 19) printf("\n");
55414396Sslatteng }
55514396Sslatteng printf("\n");
55614396Sslatteng }
55714967Sslatteng #endif
55814396Sslatteng
55914967Sslatteng
loadfont(n,s,s1)56014396Sslatteng loadfont(n, s, s1) /* load font info for font s on position n (0...) */
56114396Sslatteng int n;
56214396Sslatteng char *s, *s1;
56314396Sslatteng {
56414396Sslatteng char temp[60];
56514967Sslatteng int fin, nw;
56614396Sslatteng
56714396Sslatteng if (n < 0 || n > NFONT)
56814396Sslatteng error(FATAL, "illegal fp command %d %s", n, s);
56914396Sslatteng if (fontbase[n] != NULL && strcmp(s, fontbase[n]->namefont) == 0)
57014396Sslatteng return;
57116428Sslatteng
57216428Sslatteng for (fin = 1; fin <= NFONT; fin++) /* first check to see if the */
57316428Sslatteng if (strcmp(s, fontbase[fin]->namefont) == 0) { /* font is loaded */
57416428Sslatteng register unsigned char *c; /* somewhere else */
57516428Sslatteng
57616428Sslatteng #define ptrswap(x, y) { c = (unsigned char*) (x); x = y; y = c; }
57716428Sslatteng #define ptrfswap(x, y) { c=(unsigned char*)(x); x = y; y = (struct font *) c; }
57816428Sslatteng
57916428Sslatteng ptrfswap(fontbase[n], fontbase[fin]);
58016428Sslatteng ptrswap(codetab[n], codetab[fin]);
58116428Sslatteng ptrswap(widtab[n], widtab[fin]);
58216428Sslatteng ptrswap(fitab[n], fitab[fin]);
58316428Sslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
58416428Sslatteng t_fp(fin, fontbase[fin]->namefont, fontbase[fin]->intname);
58516428Sslatteng return;
58616428Sslatteng }
58716428Sslatteng
58814396Sslatteng if (s1 == NULL || s1[0] == '\0')
58914967Sslatteng sprintf(temp, "%s/devip/%s.out", fontdir, s);
59014396Sslatteng else
59114396Sslatteng sprintf(temp, "%s/%s.out", s1, s);
59214396Sslatteng if ((fin = open(temp, 0)) < 0) {
59314396Sslatteng error(!FATAL, "can't open font table %s", temp);
59414396Sslatteng return;
59514396Sslatteng }
59614396Sslatteng if (fontbase[n] != NULL)
59714396Sslatteng free(fontbase[n]);
59814396Sslatteng fontbase[n] = (struct font *) malloc(3*255 + dev.nchtab +
59914396Sslatteng (128-32) + sizeof(struct font));
60014396Sslatteng if (fontbase[n] == NULL)
60114396Sslatteng error(FATAL, "Out of space in loadfont %s", s);
60214396Sslatteng read(fin, fontbase[n], 3*255 + nchtab+128-32 + sizeof(struct font));
60314396Sslatteng close(fin);
60414396Sslatteng nw = fontbase[n]->nwfont & BMASK;
60514967Sslatteng widtab[n] = (unsigned char *) fontbase[n] + sizeof(struct font);
60614967Sslatteng codetab[n] = (unsigned char *) widtab[n] + 2 * nw;
60714967Sslatteng fitab[n] = (unsigned char *) widtab[n] + 3 * nw;
60814396Sslatteng t_fp(n, fontbase[n]->namefont, fontbase[n]->intname);
60914967Sslatteng #ifdef DEBUGABLE
61014396Sslatteng if (dbg > 1) fontprint(n);
61114967Sslatteng #endif
61214396Sslatteng }
61314396Sslatteng
61414967Sslatteng
61514967Sslatteng /*VARARGS2*/
error(f,s,a1,a2,a3,a4,a5,a6,a7)61614967Sslatteng error(f, s, a1, a2, a3, a4, a5, a6, a7)
61714967Sslatteng int f;
61814967Sslatteng char *s;
61914396Sslatteng {
62014396Sslatteng fprintf(stderr, "dip: ");
62114396Sslatteng fprintf(stderr, s, a1, a2, a3, a4, a5, a6, a7);
62214396Sslatteng fprintf(stderr, "\n");
62314396Sslatteng if (f)
62415278Sslatteng exit(2);
62514396Sslatteng }
62614396Sslatteng
62714396Sslatteng
t_init()62816406Sslatteng t_init() /* initialize device */
62914396Sslatteng {
63016406Sslatteng drawthick(3); /* set the line thickness parameter */
63114396Sslatteng hpos = vpos = 0;
63214396Sslatteng setsize(t_size(10)); /* start somewhere */
63314396Sslatteng }
63414396Sslatteng
63514396Sslatteng
63614967Sslatteng /*----------------------------------------------------------------------------*
63714967Sslatteng | Routine: t_page ( page_number )
63814967Sslatteng |
63914967Sslatteng | Results: mark this page done for printing. If we think we've filled
64014967Sslatteng | the imagen too much, delete some of the info in the glyph cache.
64114967Sslatteng | This is a good time to do this since it's at the end of a page
64214967Sslatteng | and will get done every so often.
64314967Sslatteng *----------------------------------------------------------------------------*/
64414967Sslatteng
t_page(pg)64514396Sslatteng t_page(pg) /* do whatever new page functions */
64614396Sslatteng {
64714967Sslatteng register int i;
64814967Sslatteng register int threshold;
64914396Sslatteng
65014396Sslatteng pageno = pg;
65114967Sslatteng #ifdef DEBUGABLE
65214396Sslatteng if(dbg)fprintf(stderr, "t_page %d, output=%d\n", pg, output);
65314967Sslatteng #endif
65414967Sslatteng if (output != 0)
65514396Sslatteng putc(AEND, tf);
65614396Sslatteng output = in_olist(pg);
65714967Sslatteng
65814396Sslatteng if (output) {
65914967Sslatteng threshold = BOTTOMTHRESH;
66014967Sslatteng while (totglyph >= maxglyph) {
66114967Sslatteng for (i = 0; i < NFONT; i++) {
66214967Sslatteng if (fontdata[i].font != -1)
66314967Sslatteng clearglyphs(i, threshold);
66414396Sslatteng }
66514967Sslatteng threshold += DELTATHRESH;
66614967Sslatteng }
66714396Sslatteng }
66814396Sslatteng lastx = lasty = -1;
66916406Sslatteng hpos = vpos = 0;
67014396Sslatteng }
67114396Sslatteng
67214396Sslatteng
t_size(n)67314396Sslatteng t_size(n) /* convert integer to internal size number*/
67414396Sslatteng int n;
67514396Sslatteng {
67614396Sslatteng int i;
67714396Sslatteng
67814396Sslatteng if (n <= pstab[0])
67916406Sslatteng return(0);
68014396Sslatteng else if (n >= pstab[nsizes-1])
68114967Sslatteng return(nsizes-1);
68214396Sslatteng for (i = 0; n > pstab[i]; i++)
68314396Sslatteng ;
68414967Sslatteng return(i);
68514396Sslatteng }
68614396Sslatteng
68714967Sslatteng
t_charht(n)68814396Sslatteng t_charht(n) /* set character height to n */
68914396Sslatteng int n;
69014396Sslatteng {
69114396Sslatteng /* punt for now */
69214396Sslatteng }
69314396Sslatteng
69414967Sslatteng
t_slant(n)69514396Sslatteng t_slant(n) /* set slant to n */
69614396Sslatteng int n;
69714396Sslatteng {
69814396Sslatteng /* punt for now */
69914396Sslatteng }
70014396Sslatteng
70114967Sslatteng
t_font(s)70214396Sslatteng t_font(s) /* convert string to internal font number */
70314396Sslatteng char *s;
70414396Sslatteng {
70514396Sslatteng int n;
70614396Sslatteng
70714396Sslatteng n = atoi(s);
70814396Sslatteng if (n < 0 || n > nfonts)
70914396Sslatteng n = 1;
71014396Sslatteng return(n);
71114396Sslatteng }
71214396Sslatteng
71314396Sslatteng
t_wrapup()71414396Sslatteng t_wrapup()
71514396Sslatteng {
71614396Sslatteng putc(AEND, tf);
71714396Sslatteng putc(AEOF, tf);
71814396Sslatteng }
71914396Sslatteng
72014396Sslatteng
put1s(s)72114396Sslatteng put1s(s) /* s is a funny char name */
72214967Sslatteng register char *s;
72314396Sslatteng {
72414396Sslatteng static int i = 0;
72514396Sslatteng
72614396Sslatteng if (!output)
72714396Sslatteng return;
72814967Sslatteng #ifdef DEBUGABLE
72914396Sslatteng if (dbg) printf("%s ", s);
73014967Sslatteng #endif
73114396Sslatteng if (strcmp(s, &chname[chtab[i]]) != 0)
73214396Sslatteng for (i = 0; i < nchtab; i++)
73314396Sslatteng if (strcmp(&chname[chtab[i]], s) == 0)
73414396Sslatteng break;
73514396Sslatteng if (i < nchtab)
73614396Sslatteng put1(i + 128);
73714396Sslatteng else
73814396Sslatteng i = 0;
73914396Sslatteng }
74014396Sslatteng
74114967Sslatteng
put1(c)74214396Sslatteng put1(c) /* output char c */
74314967Sslatteng register int c;
74414396Sslatteng {
74514967Sslatteng register unsigned char *pw;
74614967Sslatteng register unsigned char *p;
74714967Sslatteng register int i;
74814967Sslatteng register int j;
74914967Sslatteng register int k;
75014967Sslatteng int ofont, code;
75114396Sslatteng
75214396Sslatteng if (!output)
75314396Sslatteng return;
75414396Sslatteng c -= 32;
75514396Sslatteng if (c <= 0) {
75614967Sslatteng #ifdef DEBUGABLE
75714396Sslatteng if (dbg) printf("non-exist 0%o\n", c+32);
75814967Sslatteng #endif
75914396Sslatteng return;
76014396Sslatteng }
76114967Sslatteng ofont = font;
76214967Sslatteng i = fitab[font][c];
76314396Sslatteng if (i != 0) { /* it's on this font */
76414396Sslatteng p = codetab[font];
76514967Sslatteng pw = widtab[font];
76614967Sslatteng } else { /* on another font */
76715278Sslatteng k = font; /* start with current, then run down the list */
76814967Sslatteng for (j=0; j++ <= nfonts; k = (k+1) % (nfonts+1))
76914967Sslatteng if (fontbase[k] != NULL && (i = fitab[k][c]) != 0) {
77014396Sslatteng p = codetab[k];
77114967Sslatteng pw = widtab[k];
77214396Sslatteng setfont(k);
77314396Sslatteng break;
77414396Sslatteng }
77514396Sslatteng }
77614967Sslatteng code = p[i] & BMASK;
77714967Sslatteng if (i == 0) {
77814967Sslatteng #ifdef DEBUGABLE
77914396Sslatteng if (dbg) printf("not found 0%o\n", c+32);
78014967Sslatteng #endif
78114396Sslatteng return;
78214396Sslatteng }
78314967Sslatteng lastw = (pw[i] * pstab[size] + dev.unitwidth/2) / dev.unitwidth;
78414967Sslatteng #ifdef DEBUGABLE
78514396Sslatteng if (dbg) {
78614396Sslatteng if (isprint(c+32))
78714396Sslatteng printf("%c %d\n", c+32, code);
78814396Sslatteng else
78914396Sslatteng printf("%03o %d\n", c+32, code);
79014396Sslatteng } else
79114967Sslatteng #endif
79214967Sslatteng if (output) xychar(code);
79314396Sslatteng if (font != ofont)
79414396Sslatteng setfont(ofont);
79514396Sslatteng }
79614396Sslatteng
79714967Sslatteng
setsize(n)79814396Sslatteng setsize(n) /* set point size to n (internal) */
79914396Sslatteng int n;
80014396Sslatteng {
80114396Sslatteng size = n;
80214396Sslatteng }
80314396Sslatteng
80414396Sslatteng
80514967Sslatteng /*----------------------------------------------------------------------------*
80614967Sslatteng | Routine: t_fp ( number, string, string_internal )
80714967Sslatteng |
80814967Sslatteng | Results: font position number now contains font 'string', internal
80914967Sslatteng | font name (number) is ignored.
81014967Sslatteng |
81114967Sslatteng | Side Efct: any fonts loaded into fontdata with this font number are
81214967Sslatteng | removed. And, to make sure they're not accessed, if lastfont
81314967Sslatteng | equals number, it is "disabled" by setting lastfont to -1.
81414967Sslatteng *----------------------------------------------------------------------------*/
81514396Sslatteng
t_fp(n,s,si)81614967Sslatteng t_fp(n, s, si)
81714396Sslatteng int n;
81814396Sslatteng char *s, *si;
81914396Sslatteng {
82014967Sslatteng register int i;
82114967Sslatteng
82214967Sslatteng fontname[n] = s;
82314967Sslatteng for (i = 0; i <= NFONT; i++) /* release any font files */
82414967Sslatteng if (fontdata[i].font == n) { /* for this font */
82514967Sslatteng clearglyphs (i, 1000);
82614967Sslatteng putc(AFORCE, tf);
82714967Sslatteng free (fontdata[i].cdp);
82814967Sslatteng free (fontdata[i].glyph);
82914967Sslatteng fontdata[i].font = -1;
83014967Sslatteng }
83114967Sslatteng if (n == lastfont) lastfont = -1;
83214396Sslatteng }
83314396Sslatteng
83414967Sslatteng
setfont(n)83514396Sslatteng setfont(n) /* set font to n */
83614396Sslatteng int n;
83714396Sslatteng {
83814396Sslatteng if (!output)
83914396Sslatteng return;
84016406Sslatteng if (n < 0 || n > nfonts)
84114396Sslatteng error(FATAL, "illegal font %d", n);
84214396Sslatteng font = n;
84314396Sslatteng }
84414396Sslatteng
84514967Sslatteng
setstip(n)84616406Sslatteng setstip(n) /* set stipple "font" to n */
84716406Sslatteng int n;
84816406Sslatteng {
84916406Sslatteng if (!output)
85016406Sslatteng return;
85116406Sslatteng if (n < 1 || n > nstips)
85216406Sslatteng error(FATAL, "illegal stipple %d", n);
85316406Sslatteng stip = n;
85416406Sslatteng }
85516406Sslatteng
85616406Sslatteng
85714967Sslatteng /*----------------------------------------------------------------------------*
85814967Sslatteng | Routine: rd1, rd2, rd3, rd4 ( file_pointer )
85914967Sslatteng |
86014967Sslatteng | Results: gets one, two three or four bytes from a file and interprets
86114967Sslatteng | them as integers. Most significant bytes come first.
86214967Sslatteng *----------------------------------------------------------------------------*/
86314967Sslatteng
rd1(fp)86414967Sslatteng int rd1(fp)
86514967Sslatteng FILE *fp;
86614396Sslatteng {
86714967Sslatteng register int i;
86814967Sslatteng
86914967Sslatteng if((i = getc(fp)) == EOF) error(FATAL, "font file read error");
87014967Sslatteng return i;
87114396Sslatteng }
87214396Sslatteng
rd2(fp)87314967Sslatteng int rd2(fp)
87414967Sslatteng FILE *fp;
87514967Sslatteng {
87614967Sslatteng register short i = rd1(fp) << 8;
87714396Sslatteng
87814967Sslatteng return i | rd1(fp);
87914967Sslatteng }
88014396Sslatteng
rd3(fp)88114967Sslatteng int rd3(fp)
88214967Sslatteng FILE *fp;
88314967Sslatteng {
88414967Sslatteng register int i = rd2(fp) << 8;
88514396Sslatteng
88614967Sslatteng return i | rd1(fp);
88714967Sslatteng }
88814396Sslatteng
rd4(fp)88914967Sslatteng int rd4(fp)
89014967Sslatteng FILE *fp;
89114396Sslatteng {
89214967Sslatteng register int i = rd2(fp) << 16;
89314396Sslatteng
89414967Sslatteng return i | rd2(fp);
89514396Sslatteng }
89614396Sslatteng
89714967Sslatteng
89814967Sslatteng /*----------------------------------------------------------------------------*
89914967Sslatteng | Routine: getfontdata ( font, size )
90014967Sslatteng |
901*25330Sslatteng | Results: returns the family number of the font/size found. If the
902*25330Sslatteng | particular point size requested is not found, other sizes are
903*25330Sslatteng | searched for. The font information pointer, fs, is set to
904*25330Sslatteng | point to data for "font" at point size "size". If no infor-
905*25330Sslatteng | mation for that font is available, the info is read in from
906*25330Sslatteng | the appropriate font file. The table "fontdata" holds all the
907*25330Sslatteng | fonts, and it is cleared of a random font/size if necessary.
90814967Sslatteng *----------------------------------------------------------------------------*/
90914967Sslatteng
getfontdata(f,s)91014967Sslatteng int getfontdata(f, s)
91114967Sslatteng int f;
91214967Sslatteng int s;
91314396Sslatteng {
91414396Sslatteng char name[100];
91514967Sslatteng register FILE *fd;
91614967Sslatteng register int i;
91714967Sslatteng register int fam;
91814967Sslatteng register int bitbase;
91914967Sslatteng register glyph_dir *maxgp;
92014967Sslatteng register glyph_dir *gp;
92114967Sslatteng preamble p;
92214396Sslatteng
92314967Sslatteng /* first check if it's here already */
92414967Sslatteng for (fam = 0; fam <= NFONT; fam++)
92514967Sslatteng if (fontdata[fam].font == f && fontdata[fam].size == s) {
92614967Sslatteng fs = &fontdata[fam];
92714967Sslatteng return (fam);
92814967Sslatteng }
92914967Sslatteng /* find an empty slot */
93014967Sslatteng for (fam = 0; fam < NFONT && fontdata[fam].font != -1; fam++);
93114967Sslatteng fs = &fontdata[fam];
93214967Sslatteng if (fs->font != -1) { /* clear a slot if not empty */
93314967Sslatteng clearglyphs(fam, 1000); /* dumb version - always take */
93414967Sslatteng putc(AFORCE, tf); /* the last one to replace */
93514967Sslatteng free(fs->glyph);
93614967Sslatteng free(fs->cdp);
93714396Sslatteng }
938*25330Sslatteng
939*25330Sslatteng bitbase = s;
940*25330Sslatteng /* try to open font file - if unsuccessful, hunt for */
941*25330Sslatteng /* a file of same style, different size to substitute */
942*25330Sslatteng i = -1; /* direction to look in pstab (smaller first) */
943*25330Sslatteng do {
944*25330Sslatteng sprintf(name, "%s/%s.%d", bitdir, fontname[f], pstab[bitbase]);
945*25330Sslatteng fd = fopen(name, "r");
946*25330Sslatteng if (fd == NULL) { /* File wasn't found. Try another ps */
947*25330Sslatteng bitbase += i;
948*25330Sslatteng if (bitbase < 0) { /* past beginning - look higher */
949*25330Sslatteng i = 1;
950*25330Sslatteng bitbase = s + i;
951*25330Sslatteng }
952*25330Sslatteng if (bitbase > nsizes) /* past top - forget it */
953*25330Sslatteng i = 0;
954*25330Sslatteng }
955*25330Sslatteng } while (fd == NULL && i != 0);
956*25330Sslatteng
957*25330Sslatteng if (fd == NULL) /* completely unsuccessful */
958*25330Sslatteng error(FATAL,"can't open %s/%s.%d",bitdir,fontname[f],pstab[s]);
95914967Sslatteng /* check for proper file mark */
96015278Sslatteng for(i = 0; i < FMARK; filemark[i++] = getc(fd));
96115278Sslatteng if (strncmp(filemark, "Rast", 4))
96214967Sslatteng error(FATAL, "bad File Mark in %s.", name);
96314967Sslatteng /* get preamble */
96414967Sslatteng p.p_size = rd2(fd);
96514967Sslatteng p.p_version = rd1(fd);
96614967Sslatteng if (p.p_version)
96714967Sslatteng error(FATAL, "wrong version of Font file: %s.", name);
96814967Sslatteng p.p_glyph = rd3(fd);
96916406Sslatteng fs->first = p.p_first = rd2(fd);
97016406Sslatteng fs->last = p.p_last = rd2(fd);
97114967Sslatteng /* skip rest of preamble */
97214967Sslatteng i = p.p_glyph - 18;
97314967Sslatteng while (i--) getc(fd);
97414967Sslatteng fs->glyph = (glyph_dir *) /* allocate first */
97514967Sslatteng ((char *) malloc((p.p_last - p.p_first + 1) * sizeof(glyph_dir))
97614967Sslatteng - (char *) (p.p_first * sizeof(glyph_dir)));
97716406Sslatteng maxgp = gp = &(fs->glyph[p.p_first]);
97816406Sslatteng bitbase = maxgp->g_bitp;
97914967Sslatteng for (i = p.p_first; i++ <= p.p_last; gp++) {
98014967Sslatteng gp->g_height = rd2(fd);
98114967Sslatteng gp->g_width = rd2(fd);
98214967Sslatteng gp->g_up = rd2(fd);
98314967Sslatteng gp->g_left = rd2(fd);
98414967Sslatteng gp->g_pwidth = rd4(fd);
98514967Sslatteng if ((gp->g_bitp = rd3(fd)) > maxgp->g_bitp) /* find the glyphs */
98616406Sslatteng maxgp = gp; /* farthest from and */
98716406Sslatteng else if(gp->g_bitp < bitbase) /* nearest to the */
98816406Sslatteng bitbase = gp->g_bitp; /* start of the file */
98914967Sslatteng }
99016406Sslatteng /* remove file offset in bit pointers */
99114967Sslatteng for (gp = fs->glyph, i = p.p_first; i++ <= p.p_last; gp++)
99214967Sslatteng gp->g_bitp -= bitbase;
99314396Sslatteng
99414967Sslatteng i = maxgp->g_bitp + maxgp->g_height * ((maxgp->g_width + 7) / 8);
99514967Sslatteng fs->cdp = (unsigned char *) malloc(i);
99614967Sslatteng lseek(fileno(fd), (long) bitbase, 0);
99714967Sslatteng if (read(fileno (fd), fs->cdp, i) != i)
99814967Sslatteng error(FATAL, "can't read in %s", name);
99914967Sslatteng fclose(fd);
100014396Sslatteng
100114967Sslatteng fs->size = s;
100214967Sslatteng fs->font = f;
100314967Sslatteng for (i = 0; i < CHARRAY; fs->chused[i++] = 0);
100414967Sslatteng return (fam);
100514396Sslatteng }
100614396Sslatteng
100714967Sslatteng
100816406Sslatteng /*----------------------------------------------------------------------------*
100916406Sslatteng | Routine: setfill(stipple_number)
101016406Sslatteng |
101116406Sslatteng | Results: sends the appropriate command to set the fill-pattern
101216406Sslatteng | for a particular stipple. Sends the glyph if necessary,
101316406Sslatteng | and does nothing if the pattern is the same. Takes stipple
101416406Sslatteng | font from current "stip" number.
101516406Sslatteng *----------------------------------------------------------------------------*/
101616406Sslatteng
setfill(number)101716406Sslatteng setfill(number)
101816406Sslatteng register int number;
101916406Sslatteng {
102016406Sslatteng register int fam;
102116406Sslatteng register int gsize;
102216406Sslatteng register glyph_dir *par;
102316406Sslatteng register unsigned char *p;
102416406Sslatteng register fontset *savefs;
102516406Sslatteng
102616406Sslatteng if (stip == laststip && number == laststipmem)
102716406Sslatteng return;
102816406Sslatteng
102916406Sslatteng savefs = fs; /* getfontdata sets fs, so we have to */
103016406Sslatteng /* save it before calling getfontdata */
103116406Sslatteng fam = getfontdata(nfonts + stip, nsizes);
103216406Sslatteng laststip = stip;
103316406Sslatteng laststipmem = number; /* must be set before call to polygon */
103416406Sslatteng
103516406Sslatteng if (!number || number < fs->first || number > fs->last) {
103616555Sslatteng nostipbits:
103716406Sslatteng fs = savefs; /* forget it if it's out of range */
103816406Sslatteng laststipmem = 0; /* force NO stipple */
103916406Sslatteng return;
104016406Sslatteng }
104116406Sslatteng if (fs->chused[number] == 0) { /* stipple not down-loaded */
104216555Sslatteng par = &(fs->glyph[number]);
104316555Sslatteng if (!par->g_bitp)
104416555Sslatteng goto nostipbits;
104516555Sslatteng totglyph += glspace(par);
104616406Sslatteng putc(ABGLY, tf);
104716406Sslatteng putint((fam << 7) | number, tf);
104816406Sslatteng putint(par->g_pwidth, tf);
104916406Sslatteng putint(par->g_width, tf);
105016406Sslatteng putint(par->g_left, tf);
105116406Sslatteng putint(par->g_height, tf);
105216406Sslatteng putint(par->g_up, tf);
105316406Sslatteng gsize = ((par->g_width + 7)/8) * par->g_height;
105416406Sslatteng p = fs->cdp + par->g_bitp;
105516406Sslatteng while (gsize--)
105616406Sslatteng putc(*p++, tf);
105716406Sslatteng }
105816406Sslatteng /* mark that it's been used */
105916406Sslatteng if (fs->chused[number] != BMASK)
106016406Sslatteng fs->chused[number]++;
106116406Sslatteng putc(ASTEXTURE, tf); /* set the texture */
106216406Sslatteng putint((fam << 7) | number, tf);
106316406Sslatteng fs = savefs; /* return fs to proper spot */
106416406Sslatteng }
106516406Sslatteng
106616406Sslatteng
xychar(c)106714396Sslatteng xychar(c)
106814967Sslatteng register int c;
106914396Sslatteng {
107014396Sslatteng register unsigned char *p;
107114967Sslatteng register glyph_dir *par;
107214967Sslatteng register int gsize;
107314396Sslatteng
107414396Sslatteng
107514967Sslatteng if (c >= CHARRAY) {
107614967Sslatteng #ifdef DEBUGABLE
107714967Sslatteng if (dbg) error(!FATAL, "character out of range: %d 0%o", c, c);
107814967Sslatteng #endif
107914967Sslatteng return;
108014967Sslatteng }
108114396Sslatteng if (font != lastfont || size != lastsize) {
108214967Sslatteng family = getfontdata(font, size);
108314396Sslatteng lastsize = size;
108414396Sslatteng lastfont = font;
108514396Sslatteng }
108614967Sslatteng par = &(fs->glyph[c]);
108714967Sslatteng p = fs->cdp + par->g_bitp;
108814967Sslatteng if (family != lastfam) {
108914396Sslatteng putc(AF, tf);
109014967Sslatteng putc(lastfam = family ,tf);
109114396Sslatteng }
109214396Sslatteng
109314967Sslatteng if (fs->chused[c] == 0) { /* 1st use of this character */
109414396Sslatteng totglyph += glspace(par);
109514967Sslatteng putc(ABGLY, tf);
109614967Sslatteng putint((family << 7) | c, tf);
109714967Sslatteng putint(lastw, tf); /* use troff's width, not */
109814967Sslatteng putint(par->g_width, tf); /* the RST character width */
109914967Sslatteng putint(par->g_left, tf);
110014967Sslatteng putint(par->g_height, tf);
110114967Sslatteng putint(par->g_up, tf);
110214967Sslatteng gsize = ((par->g_width + 7)/8) * par->g_height;
110314967Sslatteng while (gsize--)
110414396Sslatteng putc(*p++, tf);
110514396Sslatteng }
110616406Sslatteng /* note that character's been used */
110716406Sslatteng if (fs->chused[c] != BMASK)
110816406Sslatteng fs->chused[c]++;
110914967Sslatteng hvflush();
111014967Sslatteng putc(c, tf); /* guaranteed to be in range */
111114967Sslatteng lastx += lastw; /* take account of the automatic advance */
111214967Sslatteng }
111314396Sslatteng
111414396Sslatteng
111514967Sslatteng /*----------------------------------------------------------------------------*
111614967Sslatteng | Routine: hvflush ( )
111714967Sslatteng |
111814967Sslatteng | Results: force current position (hpos, vpos) on the imagen
111914967Sslatteng *----------------------------------------------------------------------------*/
112014396Sslatteng
hvflush()112114967Sslatteng hvflush()
112214396Sslatteng {
112314967Sslatteng if (vpos != lasty) {
112414967Sslatteng putc(ASETV, tf);
112514967Sslatteng putint(lasty = vpos, tf);
112614396Sslatteng }
112714967Sslatteng if (hpos != lastx) {
112814967Sslatteng putc(ASETH, tf);
112914967Sslatteng putint(lastx = hpos, tf);
113014396Sslatteng }
113114396Sslatteng }
113214396Sslatteng
113314967Sslatteng
113414967Sslatteng /*----------------------------------------------------------------------------*
113514967Sslatteng | Routine: glspace ( glyph )
113614967Sslatteng |
113714967Sslatteng | Results: returns how much space the glyph (defined by the glyph_dir
113814967Sslatteng | entry) will take in the imagen's memory.
113914967Sslatteng *----------------------------------------------------------------------------*/
114014967Sslatteng
glspace(par)114114396Sslatteng glspace(par)
114214967Sslatteng glyph_dir *par;
114314396Sslatteng {
114414967Sslatteng return 19 + ((par->g_width + 15) / 16 ) * (par->g_height);
114514967Sslatteng }
114614396Sslatteng
114714396Sslatteng
114814967Sslatteng /*----------------------------------------------------------------------------*
114914967Sslatteng | Routine: clearglyphs ( index, limit )
115014967Sslatteng |
115114967Sslatteng | Results: any glyphs downloaded into the imagen with a "chused" entry
115214967Sslatteng | less than "limit" (and > 0) are marked for deletion and their
115314967Sslatteng | space is "unrecorded" in totglyph.
115414967Sslatteng |
115514967Sslatteng | Bugs: clearglyphs does NOT check index to make sure the family exists
115614967Sslatteng *----------------------------------------------------------------------------*/
115714396Sslatteng
clearglyphs(index,limit)115814967Sslatteng clearglyphs(index, limit)
115914967Sslatteng int index;
116014967Sslatteng int limit;
116114396Sslatteng {
116214967Sslatteng register fontset *f = &fontdata[index];
116314967Sslatteng register int j;
116414396Sslatteng
116514967Sslatteng #ifdef DEBUGABLE
116614967Sslatteng if (dbg) fprintf(stderr, "clear %d family of %d (%d/%d) on page %d\n",
116714967Sslatteng index, limit, totglyph, maxglyph, pageno);
116814967Sslatteng #endif
116914967Sslatteng for (j = 0; j < CHARRAY; j++) {
117014967Sslatteng if (f->chused[j] && f->chused[j] < limit) {
117114967Sslatteng putc(ADELG, tf);
117214967Sslatteng putint(index<<7 | j, tf);
117314967Sslatteng totglyph -= glspace (&(f->glyph[j]));
117414967Sslatteng f->chused[j] = 0;
117514396Sslatteng }
117614967Sslatteng }
117714396Sslatteng }
117814396Sslatteng
117914396Sslatteng
putint(n,f)118014396Sslatteng putint(n, f)
118114396Sslatteng int n;
118214396Sslatteng FILE *f;
118314396Sslatteng {
118414396Sslatteng putc(n >> 8, f);
118514396Sslatteng putc(n & 0377, f);
118614396Sslatteng }
1187