home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1990 Chris Lewis
- */
-
-
- #include "defs.h"
-
- #ifdef PK
-
- #ifndef lint
- static char SCCSid[] = "@(#)pk.c 2.1 Copyright 90/07/18 16:51:38 Chris Lewis";
- #endif
-
- #define DRAW
- #define OUTRES 300
-
- #include "pk.h"
-
- #if defined(PARTIAL)
- #include "pkc.h"
- struct needmaps *needmaps = (struct needmaps *) NULL;
- #endif
-
- extern char *progname;
-
- static FILE *fin;
- static char *filename; /* name of *current* font being read */
- extern char *malloc();
-
- static long flag_byte;
- static repeatcount;
- static dyn_f;
-
- static readraster();
-
- static long
- get1int() { return(getc(fin)); }
-
- static long
- get2int() {
- register long c;
- c = get1int();
- c = (c<<8) | (0xff & get1int());
- return(c);
- }
-
- static long
- get4int() {
- register long c;
- c = get2int();
- c = (c << 16) | (0xffff & get2int());
- return(c);
- }
-
- static long
- get3int() {
- register long c;
- c = get2int();
- c = (c << 8) | (0xff & get1int());
- return(c);
- }
-
- #ifdef VFPRINTF
- #include <varargs.h>
- /* VARARGS */
- pkmsg(va_alist)
- va_dcl
- {
- va_list args;
- char *fmt;
-
- va_start(args);
- fmt = (char *) va_arg(args, char *);
- VFPRINTF(stderr, fmt, args);
- va_end(args);
- }
- #else
- /* VARARGS1 ARGSUSED */
- pkmsg(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)
- char *fmt;
- int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10; {
- char buf[BUFSIZ];
- sprintf(buf, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10);
- fprintf(stderr, buf);
- }
- #endif
-
- static
- skipspecials() {
- register int i,c;
- do {
- flag_byte = getc(fin);
- if (flag_byte >= 240) {
- i = 0;
- switch(flag_byte) {
- case PK_xxx4:
- i = (i << 8) + getc(fin);
- case PK_xxx3:
- i = (i << 8) + getc(fin);
- case PK_xxx2:
- i = (i << 8) + getc(fin);
- case PK_xxx1:
- i = (i << 8) + getc(fin);
- DBP((D_PK, "PK_xxx%d: ", flag_byte - PK_xxx1 + 1));
- while(i--) {
- c = getc(fin);
- DBP((D_PK, "%c", c));
- }
- DBP((D_PK, "\n"));
- break;
- case PK_yyy:
- i = get4int();
- DBP((D_PK, "Num special: %d\n", i));
- break;
- case PK_post:
- DBP((D_PK, "Postamble\n"));
- break;
- case PK_no_op:
- DBP((D_PK, "No-op\n"));
- break;
- default:
- pkmsg("PK file %s: Unexpected %ld\n", filename,
- flag_byte);
- exit(1);
- }
- }
- } while (flag_byte >= 240 && flag_byte != PK_post);
- }
-
- static
- readschar(p)
- struct pkc *p; {
- p->pkc_pl = get1int() + ((p->pkc_flag&0x3) << 8);
- p->pkc_char = get1int();
- p->pkc_tfm = get3int();
- p->pkc_dx = get1int() * pow2(16);
- p->pkc_dy = 0;
- p->pkc_width = get1int();
- p->pkc_height = get1int();
- p->pkc_x_off = get1int();
- p->pkc_y_off = get1int();
- if (p->pkc_x_off > 127)
- p->pkc_x_off -= 256;
- if (p->pkc_y_off > 127)
- p->pkc_y_off -= 256;
- p->pkc_rlen = p->pkc_pl - 8;
- readraster(p);
- }
-
- static
- readeschar(p)
- struct pkc *p; {
- p->pkc_pl = get2int() + ((p->pkc_flag&0x3) << 16);
- p->pkc_char = get1int();
- p->pkc_tfm = get3int();
- p->pkc_dx = get2int() * pow2(16);
- p->pkc_dy = 0;
- p->pkc_width = get2int();
- p->pkc_height = get2int();
- p->pkc_x_off = get2int();
- p->pkc_y_off = get2int();
- if (p->pkc_x_off > 32767)
- p->pkc_x_off -= 65536;
- if (p->pkc_y_off > 32767)
- p->pkc_y_off -= 65536;
- p->pkc_rlen = p->pkc_pl - 13;
- readraster(p);
- }
-
- static
- readlchar(p)
- struct pkc *p; {
- p->pkc_pl = get4int();
- p->pkc_char = get4int();
- p->pkc_tfm = get4int();
- p->pkc_dx = get4int();
- p->pkc_dy = get4int();
- p->pkc_width = get4int();
- p->pkc_height = get4int();
- p->pkc_x_off = get4int();
- p->pkc_y_off = get4int();
- p->pkc_rlen = p->pkc_pl - 28;
- readraster(p);
- }
-
- static
- readraster(p)
- struct pkc *p; {
- p->pkc_pkr = (int8 *) mustmalloc((int) p->pkc_rlen, filename);
- fread((char *) p->pkc_pkr, 1, (int) p->pkc_rlen, fin);
- }
-
- /* Read a character sequence from a PK file */
- static struct pkc *
- rpkc() {
- register struct pkc *p = (struct pkc *) mustmalloc(sizeof(struct pkc),
- filename);
-
- p->pkc_pkr = NULL;
- p->pkc_sfpr = NULL;
- p->pkc_flag = flag_byte;
- p->pkc_dyn_f = p->pkc_flag >> 4;
- flag_byte &= 0x7;
-
- if (flag_byte == 7)
- readlchar(p);
- else if (flag_byte > 3)
- readeschar(p);
- else
- readschar(p);
- return(p);
- }
-
- #ifdef SFP
- /* Read a character sequence from an SFP */
- static struct pkc *
- rsfpc() {
- register struct pkc *p;
- int len;
-
- if ((len = getc(fin)) == EOF || len != '\033') {
- /* HP fonts when loaded often have trailing nulls due to DOS
- file padding. Screech on non-null */
- if (len && len != EOF)
- fprintf(stderr,
- "%s: WARNING: trailing garbage in %s, offset %ld, char 0x%02x\n",
- progname, filename, ftell(fin), len);
- flag_byte = PK_post;
- return((struct pkc *) NULL);
- }
-
- p = (struct pkc *) mustmalloc(sizeof(struct pkc), filename);
- p->pkc_pkr = NULL;
- p->pkc_sfpr = NULL;
- p->pkc_flag = 0;
- p->pkc_dyn_f = 0;
-
- if (fscanf(fin, "*c%ldE", &(p->pkc_char)) != 1) {
- pkmsg("SFP file: %s, bad/missing SET CHAR CODE, offset: %ld\n",
- filename, ftell(fin));
- exit(1);
- }
-
- if (fscanf(fin, "\033(s%dW", &len) != 1 || len < 16) {
- pkmsg("SFP file: %s, bad/missing/tooshort CHAR DOWNLOAD sequence\n",
- filename);
- exit(1);
- }
-
- get4int(); /* skip some garbage */
- get2int(); /* skip more garbage (actually, orientation & dummy */
-
- p->pkc_x_off = get2int();
- if (p->pkc_x_off > 32767)
- p->pkc_x_off -= 65536;
- p->pkc_x_off = -p->pkc_x_off;
- p->pkc_y_off = get2int();
- if (p->pkc_y_off > 32767)
- p->pkc_y_off -= 65536;
- p->pkc_width = get2int();
- p->pkc_height = get2int();
- p->pkc_dx = get2int() * pow2(16) / 4;
-
- p->pkc_sfpr = (struct ras *) mustmalloc(sizeof(struct ras), filename);
-
- p->pkc_sfpr->ras_height = p->pkc_height;
- p->pkc_sfpr->ras_width = p->pkc_width;
- p->pkc_sfpr->ras_bline = (p->pkc_width + 7) / 8;
- p->pkc_sfpr->ras_bytes = p->pkc_sfpr->ras_height * p->pkc_sfpr->ras_bline;
- if (p->pkc_sfpr->ras_bytes) {
- p->pkc_sfpr->ras_raster = (int8 *) mustmalloc((int)
- p->pkc_sfpr->ras_bytes, filename);
-
- fread((char *) p->pkc_sfpr->ras_raster, (int) p->pkc_sfpr->ras_bytes,
- 1, fin);
- } else {
- free((char *) p->pkc_sfpr);
- p->pkc_sfpr = NULL;
- }
-
- return(p);
- }
- #endif
-
- static struct pkc *
- readchar(p)
- struct pkp *p; {
- if (p->pkp_flags&PK_PK)
- return(rpkc());
- #ifdef SFP
- else if (p->pkp_flags&PK_SFP)
- return(rsfpc());
- #endif
- else
- return((struct pkc *) NULL);
- }
-
- static int
- pkccomp(a, b)
- struct pkc **a, **b; {
- if ((*a)->pkc_char < (*b)->pkc_char)
- return(-1);
- else
- return(1);
- /* can't be equal! */
- }
-
- static
- rastbit(x,y,r)
- register int x, y;
- register struct ras *r; {
- register int bi = y * r->ras_bline + (x >> 3);
-
- /* You don't really want to uncomment this.... ;-) */
- /* printf("x,y,bi: %d,%d,%d\n", x, y, bi);*/
- return(r->ras_raster[bi] & (0x80 >> (x&7)));
- }
-
- static int8 *rptr;
- static long bitweight;
-
- getnyb() {
- register int8 b;
- if (!bitweight) {
- bitweight = 8;
- rptr++;
- }
- b = *rptr;
- bitweight -= 4;
- #ifdef VDEBUG
- DBP((D_PK, "getnyb byte: %x\n", b));
- DBP((D_PK, "getnyb: %x\n", (b >> bitweight) & 0xf));
- #endif
- return((b >> bitweight)&0xf);
- }
-
- #ifdef NEVER
- getbit() {
- register int8 b;
- if (!bitweight) {
- bitweight = 8;
- rptr++;
- }
- b = *rptr;
- bitweight--;
- return((b>>bitweight)&1);
- }
- #endif
-
- /* Dumps an ASCII version of the SFP raster r, to line n.
- Normally only for debugging, but is also used from pktype
- */
-
- dumpr(r, n)
- struct ras *r;
- int n; {
- int x, y;
- if (!diagFile)
- return;
- fprintf(diagFile, "\n");
- for (y = 0; y < n; y++) {
- fprintf(diagFile, "%3d ", y);
- for (x = 0; x < r->ras_width; x++) {
- if (rastbit(x, y, r))
- putc('*', diagFile);
- else
- putc(' ', diagFile);
- }
- putc('\n', diagFile);
- }
- }
-
- static long
- pkpack(pc,r)
- register struct pkc *pc;
- register struct ras *r; {
- long i, j;
- long pkpackret;
- i = getnyb();
- if (i == 0) {
- do {
- j = getnyb();
- i++;
- } while(!j);
- while(i--)
- j = (j << 4) + getnyb();
- pkpackret = (j - 15 + (13 - dyn_f) * 16 + dyn_f);
- } else if (i <= dyn_f)
- pkpackret = (i);
- else if (i < 14)
- pkpackret = ((i - dyn_f - 1)*16 + getnyb() + dyn_f + 1);
- else {
- if (repeatcount) {
- pkmsg("Second repeat count for this row!\n");
- exit(1);
- }
- if (i == 14)
- repeatcount = pkpack(pc,r);
- else
- repeatcount = 1;
- /*sendout(1, repeatcount, pc, r);*/
- pkpackret = (pkpack(pc,r));
- }
- if (pkpackret < 1) {
- pkmsg("pkpack returned < 1! (%s)", filename);
- exit(1);
- }
- return(pkpackret);
- }
-
- static
- getpbits(pc, r)
- register struct pkc *pc;
- register struct ras *r; {
- register int h_bit = pc->pkc_width,
- count,
- turnon;
- turnon = pc->pkc_flag&0x8;
- dyn_f = pc->pkc_dyn_f;
- repeatcount = 0;
- r->ras_xcur = r->ras_ycur = 0;
- while(r->ras_ycur < pc->pkc_height) {
- count = pkpack(pc,r);
- while(count > 0) {
- if (count >= h_bit) {
- count -= h_bit;
- while(h_bit--) {
- if (turnon)
- r->ras_raster[r->ras_ycur*r->ras_bline + (r->ras_xcur>>3)]
- |= (0x80 >> (r->ras_xcur&7));
- r->ras_xcur++;
- }
- r->ras_ycur++;
- r->ras_xcur = 0;
- while(repeatcount --) {
- #ifdef VDEBUG
- DBP((D_PK, "Copy line %d to %d\n", r->ras_ycur,
- r->ras_ycur-1));
- #endif
- memcpy((char*)&(r->ras_raster[r->ras_ycur * r->ras_bline]),
- (char*)&(r->ras_raster[(r->ras_ycur - 1) *
- r->ras_bline]),
- (int) r->ras_bline);
- r->ras_ycur++;
- }
- repeatcount = 0;
- h_bit = pc->pkc_width;
- } else {
- h_bit -= count;
- while(count--) {
- if (turnon)
- r->ras_raster[r->ras_ycur*r->ras_bline +
- (r->ras_xcur>>3)] |= (0x80 >> (r->ras_xcur&7));
- r->ras_xcur++;
- }
- count = 0;
- }
- }
- turnon = !turnon;
- }
- if (r->ras_ycur != pc->pkc_height ||
- h_bit != pc->pkc_width)
- pkmsg("Bad bit somehow (%s)\n", filename);
- }
-
- static
- getrbits(pc, r)
- register struct pkc *pc;
- register struct ras *r; {
- register int x, y;
- register int bit = 0;
- for (y = 0; y < pc->pkc_height; y++) {
- for (x = 0; x < pc->pkc_width; x++) {
- if (pc->pkc_pkr[bit >> 3] & (0x80 >> (bit&7)))
- r->ras_raster[y*r->ras_bline + (x>>3)] |= (0x80 >> (x&7));
- bit++;
- }
- }
- }
-
- /* Convert a PK raster to an unpacked SFP version.
- (If there's already an SFP version, it's returned instead)
- */
- struct ras *
- pkrast(pc)
- struct pkc *pc; {
- register struct ras *r;
- if (pc->pkc_sfpr)
- return(pc->pkc_sfpr);
- if (!pc->pkc_rlen)
- return(NULL);
-
- pc->pkc_sfpr = r = (struct ras *) mustmalloc(sizeof(struct ras),
- filename);
-
- r->ras_height = pc->pkc_height;
- r->ras_width = pc->pkc_width;
- r->ras_bline = (pc->pkc_width + 7) / 8;
- r->ras_bytes = r->ras_height * r->ras_bline;
- r->ras_raster = (int8 *) mustmalloc((int) r->ras_bytes, filename);
-
- /* initialize bit unpackers */
- rptr = pc->pkc_pkr;
- bitweight = 8;
-
- /* calculate bits here...*/
- if (pc->pkc_dyn_f == 14)
- getrbits(pc, r);
- else
- getpbits(pc, r);
- return(r);
- }
-
- /* Read a PK font file header */
- static struct pkp *
- pk_rpk(p)
- register struct pkp *p; {
- register int i,c;
-
- if (getc(fin) != 89) {
- pkmsg("PK file %s: Wrong version of packed file!\n", filename);
- exit(1);
- }
- i = getc(fin);
- if (i > 0) {
- DBP((D_PK, "PKVersion: "));
- while (i--) {
- c = getc(fin);
- DBP((D_PK, "%c", c));
- }
- DBP((D_PK, "\n"));
- }
- p->pkp_bmax = 0;
- p->pkp_dmax = 0;
- p->pkp_wmax = 0;
- p->pkp_xomax = 0;
- p->pkp_ds = get4int();
- p->pkp_cs = get4int();
- p->pkp_hppp = get4int();
- p->pkp_vppp = get4int();
-
- if (p->pkp_hppp != p->pkp_vppp)
- pkmsg("PK file %s: Warning aspect ratio not 1:1\n", filename);
- p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
- p->pkp_npts = ((double) p->pkp_ds / pow2(20)) *
- ((double) p->pkp_res / OUTRES) + .5;
- p->pkp_chars = (struct pkc *) NULL;
- p->pkp_last = (struct pkc *) NULL;
- p->pkp_num = 0;
- p->pkp_list = (struct pkc **) NULL;
-
- /* Try to guess symset, style, stroke weight and typeface
- These aren't particularly important, but it assists the LJ
- if it's trying to select one of these via characteristic.
- This will only work if the file name reflects the Troff name,
- according to the following conventions:
-
- filename: {<path>/}troffname.pointsize.[pk|sfp]
-
- All ROMAN8 encodings unless MATH8.
- All 0 strokeweight, unless Bold.
- All upright, unless Italic
- All Roman typeface, unless otherwise specified
-
- R : Normal Roman
- I : Italic
- B : Bold
- S : MATH8 Symbol
- X : Bold italic
- .X : <typeface> Bold italic
- .I : <typeface> Italic
- .B : <typeface> Bold
- .R : <typeface> Normal
- H or H. : Helvetica typeface
- C or C. : Courier typeface
- typefaces should be extended.
- */
-
- {
- register char *fp;
- register int char1, char2, italic, bold, bolditalic, onechar;
-
- fp = strrchr(filename, '/');
- if (!fp)
- fp = filename;
- else
- fp++;
-
- /* Default settings */
- p->pkp_symset = (8 << 5) - 64 + 'U'; /* ROMAN 8 */
- p->pkp_style = 0; /* upright */
- p->pkp_sw = 0; /* stroke 0 */
- p->pkp_typeface = 5; /* typeface Roman */
-
- char1 = *fp++;
- onechar = (*fp == '.');
-
- if (char1 == 'S' && onechar)
- p->pkp_symset = (8 << 5) - 64 + 'M'; /* MATH 8 */
- else {
-
- char2 = *fp;
-
- italic = ((onechar && char1 == 'I') || char2 == 'I');
- bold = ((onechar && char1 == 'B') || char2 == 'B');
- bolditalic = ((onechar && char1 == 'X') || char2 == 'X');
-
- if (bold || bolditalic)
- p->pkp_sw = 3;
-
- if (italic || bolditalic)
- p->pkp_style = 1;
-
- /* This should be extended, but I don't have a good feeling
- for troff typeface -> HPLJ nomenclature */
- switch(char1) {
- case 'H':
- p->pkp_typeface = 4; /* Helvetica */
- break;
- case 'C':
- p->pkp_typeface = 3; /* Courier */
- break;
- /* more? */
- }
- }
- }
-
- return(p);
- }
-
- #ifdef SFP
-
- /* Read an SFP header and convert it into the PK internal structure.
- */
- static struct pkp *
- pk_rsfp(p)
- register struct pkp *p; {
- register int c;
- int len;
-
- if (fscanf(fin, ")s%dW", &len) != 1) {
- pkmsg("SFP file %s: Bad CREATE FONT sequence\n", filename);
- exit(1);
- }
-
- if (len < 26) {
- pkmsg("SFP file %s: CREATE FONT sequence too short (%d)\n",
- filename, len);
- exit(1);
- }
-
- get2int(); /* 26 */
- get1int(); /* 0 */
- get1int(); /* 0 or 1 - forced 1 anyways */
- get2int(); /* dummy */
-
- p->pkp_bmax = get2int(); /* baseline */
- p->pkp_wmax = get2int(); /* cell width */
- p->pkp_dmax = get2int() - p->pkp_bmax; /* cell height */
-
- get1int(); /* 0 port, 1 land - forced 0 */
- get1int(); /* fixed/proportional - forced proportional */
-
- p->pkp_symset = get2int();
-
- get2int(); /* pitch - we calculate this from height */
- c = get2int(); /* retrieved *height* */
- p->pkp_npts = c * POINT / (OUTRES*4) + .5;
-
- get2int(); /* dummy */
- get1int(); /* dummy */
-
- p->pkp_style = get1int();
- p->pkp_sw = get1int();
- p->pkp_typeface = get1int();
-
- p->pkp_xomax = 0;
-
- /* These are simulated so that the PK handlers can figure the font out */
- p->pkp_ds = p->pkp_npts * pow2(20);
- p->pkp_cs = 0;
- p->pkp_hppp = OUTRES * pow2(16) / POINT;
- p->pkp_vppp = OUTRES * pow2(16) / POINT;
- p->pkp_res = (double) p->pkp_hppp * POINT / pow2(16) + .5;
-
- p->pkp_chars = (struct pkc *) NULL;
- p->pkp_last = (struct pkc *) NULL;
- p->pkp_num = 0;
- p->pkp_list = (struct pkc **) NULL;
-
-
- len -= 26;
- while(len--)
- getc(fin);
- return(p);
- }
- #endif
-
- static struct pkp *
- readhead() {
- register struct pkp *p = (struct pkp *) mustmalloc(sizeof(struct pkp),
- filename);
- switch(getc(fin)) {
- case PK_pre:
- p->pkp_flags |= PK_PK;
- return(pk_rpk(p));
- #ifdef SFP
- case 0x1b:
- p->pkp_flags |= PK_SFP;
- flag_byte = 0;
- return(pk_rsfp(p));
- #endif
- default:
- fprintf(stderr, "PK file: %s don't know what it is!\n",
- filename);
- exit(1);
- }
- /*NOTREACHED*/
- }
-
- pk_destroy(p)
- register struct pkp *p; {
- register struct pkc *pc, *opc;
- for (pc = p->pkp_chars; pc;) {
- if (pc->pkc_pkr)
- free((char *) pc->pkc_pkr);
-
- if (pc->pkc_sfpr) {
- free((char *) pc->pkc_sfpr->ras_raster);
- free((char *) pc->pkc_sfpr);
- }
-
- opc = pc;
- pc = opc->pkc_next;
- free((char *) opc);
- }
- if (p->pkp_list)
- free((char *) p->pkp_list);
- free((char *) p);
- }
-
- struct pkp *
- pk_read(file, fontcode)
- char *file; int fontcode; {
- register struct pkp *p;
- register struct pkc *pc, **pcp;
- #ifdef COMPRESS
- int compressed = 0;
- #endif
- fin = (FILE *) NULL;
- if (access(filename = file, 4) == 0)
- fin = fopen(filename, "r");
- #ifdef COMPRESS
- else {
- char buf[1024];
- strcpy(buf, file);
- strcat(buf, ".Z");
- if (access(buf, 4) == 0) {
- sprintf(buf, "%s %s.Z", COMPRESS, file);
- fin = popen(buf, "r");
- compressed = 1;
- }
- }
- #endif
- if (!fin) {
- pkmsg("Cannot open PK/SFP file %s\n", file);
- exit(1);
- }
- p = readhead();
- if (p->pkp_flags&PK_PK)
- skipspecials();
-
- while ((flag_byte != PK_post) && (pc = readchar(p))) {
- DBP((D_VERB, "type: %s: %d\n", p->pkp_flags&PK_PK? "PK": "SFP",
- pc->pkc_char));
- #ifdef PARTIAL
- if (!needchar(fontcode, pc->pkc_char)) {
- DBP((D_FONT|D_PK, "Dropping char %02x from load\n", pc->pkc_char));
-
- if (pc->pkc_pkr) {
- free((char *) pc->pkc_pkr);
- pc->pkc_pkr = (int8 *) NULL;
- }
-
- if (pc->pkc_sfpr) {
- free((char *) pc->pkc_sfpr->ras_raster);
- free((char *) pc->pkc_sfpr);
- pc->pkc_sfpr = (struct ras *) NULL;
- }
-
- free((char *) pc);
- if (p->pkp_flags&PK_PK)
- skipspecials();
- continue;
- }
- #endif
- DBP((D_FONT|D_PK, "Loading char %02x\n", pc->pkc_char));
- p->pkp_num++;
- pc->pkc_next = (struct pkc *) NULL;
- if (!p->pkp_chars)
- p->pkp_chars = pc;
- if (p->pkp_last)
- p->pkp_last->pkc_next = pc;
- p->pkp_last = pc;
- if (p->pkp_flags&PK_PK) {
- p->pkp_bmax = max(p->pkp_bmax, pc->pkc_y_off);
- p->pkp_dmax = max(p->pkp_dmax, pc->pkc_height - pc->pkc_y_off);
- p->pkp_wmax = max(p->pkp_wmax, pc->pkc_width - pc->pkc_x_off);
- }
- p->pkp_xomax = min(p->pkp_xomax, pc->pkc_x_off);
- if (pc->pkc_char == 'a') {
- p->pkp_kh = pc->pkc_y_off;
- p->pkp_kl = pc->pkc_y_off - pc->pkc_height;
- }
- if (p->pkp_flags&PK_PK)
- skipspecials();
- }
- DBP((D_FONT|D_PK, "End of font\n"));
- #ifdef COMPRESS
- if (compressed) {
- if (pclose(fin)) {
- pkmsg("Decompression of %s failed\n", file);
- exit(1);
- }
- } else
- #endif
- fclose(fin);
- pcp = p->pkp_list = (struct pkc **)
- mustmalloc((int) (p->pkp_num * sizeof(struct pkc *)), filename);
- for (pc = p->pkp_chars; pc; pc = pc->pkc_next)
- *pcp++ = pc;
- qsort(p->pkp_list, (unsigned) p->pkp_num, sizeof(struct pkc *), pkccomp);
- return(p);
- }
-
- /* Emit routines */
-
- /* Emit a font descriptor in SFP format */
- epk_desc(p, sfp)
- register struct pkp *p;
- FILE *sfp; {
-
- fprintf(sfp, "\033)s26W");
- fputshort(26, sfp);
- fputc(0, sfp);
- fputc(1, sfp); /* font type 1 (33-127 && 160-255 printable) */
- fputshort(0, sfp);
- fputshort(p->pkp_bmax, sfp); /* baseline position */
- fputshort(p->pkp_wmax, sfp); /* cell width */
- fputshort(p->pkp_bmax + p->pkp_dmax, sfp); /* cell height */
- fputc(0, sfp); /* portrait */
- fputc(1, sfp); /* proportional */
-
- fputshort((long) p->pkp_symset, sfp);
-
- fputshort((long) (OUTRES * p->pkp_npts * 4) / 120, sfp);
- fputshort((long) (p->pkp_npts * (OUTRES / POINT) * 4), sfp);
- fputshort(0, sfp);
- fputc(0, sfp);
- fputc(p->pkp_style, sfp);
- fputc(p->pkp_sw, sfp);
- fputc(p->pkp_typeface, sfp);
-
- }
-
- fputshort(val, f)
- FILE *f;
- long val; {
- fputc(((int) val >> 8) & 0xff, f);
- fputc((int) val & 0xff, f);
- }
-
-
- /* Emit a character descriptor in SFP format.
- Notes: if this is a PK font, the PK raster is converted
- to SFP format and dumpped. If the font was originally
- SFP format, it's dumpped directly. In either event, epkc_desc
- deletes the SFP raster *and* the PK raster (if the character
- has one), meaning that once this routine has emitted a character,
- you can't emit it again! Which is why pkc's pkflush completely
- destroys the font. Why? Well, SFP's can get rather large, and
- it seems reasonable to get rid of them as quickly as possible.
-
- Returns number of bytes emitted.
- */
- epkc_desc(pc, sfp)
- register struct pkc *pc;
- register FILE *sfp; {
- register struct ras *r;
-
- if (!pc->pkc_pkr && !pc->pkc_sfpr) {
- fprintf(stderr, "%s: already downloaded %02x\n", pc->pkc_char);
- return(0);
- }
-
- /* Emit SET CHARACTER sequence */
- fprintf(sfp, "\033*c%dE", pc->pkc_char);
-
- /* Emit DOWNLOAD CHARACTER sequence */
- fprintf(sfp, "\033(s%dW", 16 + ((pc->pkc_width + 7) / 8) *
- pc->pkc_height);
- fputc(4, sfp);
- fputc(0, sfp);
- fputc(14, sfp);
- fputc(1, sfp);
- fputc(0, sfp); /* portrait */
- fputc(0, sfp);
- fputshort(-pc->pkc_x_off, sfp);
- fputshort(pc->pkc_y_off, sfp);
- fputshort(pc->pkc_width, sfp);
- fputshort(pc->pkc_height, sfp);
- fputshort(pc->pkc_dx * 4 / pow2(16), sfp);
- r = pkrast(pc);
-
- if (pc->pkc_pkr)
- free((char *) pc->pkc_pkr);
- pc->pkc_pkr = (int8 *) NULL;
-
- if (r) {
- #ifdef VDEBUG
- dumpr(r, r->ras_ycur);
- #endif
- fwrite((char *) r->ras_raster, 1, (int) ((pc->pkc_width + 7) / 8) *
- (int) pc->pkc_height, sfp);
- free((char *) r->ras_raster);
- free((char *) r);
- }
- pc->pkc_sfpr = (struct ras *) NULL;
- return(((pc->pkc_width + 7) / 8) * pc->pkc_height);
- }
- #endif
-