#include <stdio.h>
#include "dvi2ps.h"
#include "pxlfile.h"
#include "findfile.h"

struct font_entry *prevfont=NULL;  /* font_entry pointer, previous character */
struct font_entry *fontptr;     /* font_entry pointer                       */
struct font_entry *hfontptr=NULL;/* font_entry pointer                      */
struct font_entry *pfontptr = NULL; /* previous font_entry pointer          */
int    nopen = 0;
#ifdef PK
int bit_weight = 0, input_byte;
int rep_count;
int dyn_f;
#endif
#ifdef BUILTIN
struct BuiltIn {
  struct BuiltIn *next;
  char TeXname[STRSIZE];	/* TeX Name of the LaserWriter built-in font */
  char Postscript[STRSIZE];	/* Postscript definition */
  struct IncFile *include;
} *BuiltIns = NULL;

struct IncFile *IncFileList = 0;

#endif

struct pixel_list
{
    FILE *pixel_file_id;        /* file identifier                          */
    int use_count;              /* count of "opens"                         */
    };
struct pixel_list pixel_files[MAXOPEN+1];
                                /* list of open PXL file identifiers        */
#ifdef STATS
extern int Stats;
extern int   Stats;              /* are we reporting stats ?                 */
extern int   Snbpxl;             /* # of bytes of pixel data                 */
extern int   Sonbpx;            /* "optimal" number of bytes of pixel data  */
extern int   Sndc;               /* # of different characters typeset        */
extern int   Stnc;               /* total # of chars typeset                 */
extern int   Snbpx0, Sndc0, Stnc0;   /* used for printing incremental changes per dvi page */
#endif

extern FILE *dvifp;
extern int mag;
#ifdef BUILTIN
extern int PShdr;		/* PS header to be loaded? */
#endif
void	Get_Raster();
int     HasBeenRead();
#ifdef BUILTIN
int	IsBuiltIn();
#endif
void	LoadAChar();
void	OpenFontFile();
#ifdef PK
int  Pk_Packed_Num();
int  Pk_Get_Nyb();
#endif /* PK */
#ifdef BUILTIN
char   *PSDef();
#endif
int	ReadFontDef();
#ifdef BUILTIN
void	ReadMap();
#endif
#ifdef PK
void	Skip_Specials();
int	SplitPath();
void	Unpack_Raster();
#endif

/**********************************************************************/
/*************************  External Procedures  **********************/
/**********************************************************************/

float	ActualFactor();
void    EmitChar();
void	Fatal();
void	GetBytes();
void	MakePSFont();
int     NoSignExtend();
int	PixRound();
int     SignExtend();
void	Warning();

#ifdef BUILTIN
/*-->FindIncFile*/
/**********************************************************************/
/***************************  FindIncFile  ****************************/
/**********************************************************************/

struct IncFile *
FindIncFile (path, name)
char *path, *name;
{
  struct IncFile *p = IncFileList;
  char fullname[STRSIZE];

  if (name[0] != '/') {
    strcpy (fullname, path);
    if (fullname[strlen(fullname)-1] != '/') strcat (fullname, "/");
    strcat (fullname, name);
    name = fullname;
  }
  while (p) {
    if (strcmp (p->name, name) == 0) return p;
    p = p->next;
  }
				/* not found, insert it */
  p = (struct IncFile *) malloc (sizeof (struct IncFile));
  if (p == 0) Fatal ("No memory");
  p->next = IncFileList;
  p->loaded = 0;
  strcpy (p->name, name);
  return p;
}
#endif /* BUILTIN */

#ifdef PK	
/*-->Get_Raster*/
/**********************************************************************/
/*****************************  Get_Raster  ******************************/
/**********************************************************************/

void
Get_Raster(ptr)
register struct char_entry *ptr;
{
    register int ww, bw, w, j, i, c;
    register char *pr;
	pr = ptr->where.address.pixptr;
	bw = 0;
	for (i=ptr->height; i>0; i--) {
	    w = 0; ww = 0200;
	    for (j=ptr->width; j>0; j--) {
		if ((bw>>=1)==0) { bw = 0200; c = getc(pxlfp);}
		if (c&bw) w |= ww;
		if ((ww>>=1)==0) {*pr++ = w; w = 0; ww = 0200;}
	    }
	    if (ww != 0200) *pr++ = w;
	}
}
#endif /* PK */


/*-->HasBeenRead*/
/**********************************************************************/
/***************************  HasBeenRead  ****************************/
/**********************************************************************/

int
HasBeenRead(k)
int k;
{
    struct font_entry *ptr;

    ptr = hfontptr;
    while ((ptr!=NULL) && (ptr->k!=k))
	ptr = ptr->next;
    return( ptr != NULL );
}

	
#ifdef BUILTIN
/*-->IsBuiltin*/
/**********************************************************************/
/*******************************  IsBuiltin  **************************/
/**********************************************************************/
int IsBuiltIn(a)
char *a;
{
	struct BuiltIn *c;
	for(c=BuiltIns; c; c=c->next)
		if(strcmp(c->TeXname,a)==0) return(1);
	return(0);
}
#endif


/*-->LoadAChar*/
/**********************************************************************/
/*****************************  LoadAChar  ******************************/
/**********************************************************************/

void
LoadAChar(c, ptr)
int c;
register struct char_entry *ptr;
{
    char *pr;
    register int nints;

#ifdef BUILTIN
    if (fontptr->builtin) {
      if (fontptr->ncdl == 0 ) MakePSFont(fontptr);
    return;
  }
#endif

    if (ptr->where.address.fileOffset == NONEXISTANT) {
      ptr->where.address.pixptr = NULL;
      ptr->where.isloaded = TEMPORARY;
      return;
    }
    
    OpenFontFile();
    fseek(pxlfp, ptr->where.address.fileOffset, 0);
    nints = ((ptr->width + 7) >> 3) * ptr->height;
    if( (pr = (char *)malloc( nints )) == NULL )
      Fatal("Unable to allocate memory for char\n");
    ptr->where.address.pixptr = pr;
    ptr->where.isloaded = TEMPORARY;
#ifndef PK
    fread(pr, 4, nints, pxlfp);
#else
    if ((dyn_f=ptr->dyn_f) == 14) 	/* get bit-raster */
      Get_Raster(ptr);
    else 
      Unpack_Raster(ptr);
#endif /* PK */
    
    EmitChar(c, ptr);
}


/*-->OpenFontFile*/
/**********************************************************************/
/************************** OpenFontFile  *****************************/
/**********************************************************************/

void
OpenFontFile()
/***********************************************************************
    The original version of this dvi driver reopened the font file  each
    time the font changed, resulting in an enormous number of relatively
    expensive file  openings.   This version  keeps  a cache  of  up  to
    MAXOPEN open files,  so that when  a font change  is made, the  file
    pointer, pxlfp, can  usually be  updated from the  cache.  When  the
    file is not found in  the cache, it must  be opened.  In this  case,
    the next empty slot  in the cache  is assigned, or  if the cache  is
    full, the least used font file is closed and its slot reassigned for
    the new file.  Identification of the least used file is based on the
    counts of the number  of times each file  has been "opened" by  this
    routine.  On return, the file pointer is always repositioned to  the
    beginning of the file.

***********************************************************************/
{
    register int i,least_used,current;

#ifdef DEBUG
extern int Debug;
    if (Debug) printf("Open Font file\n");
#endif
    if (pfontptr == fontptr)
        return;                 /* we need not have been called */

    for (current = 1;
	(current <= nopen) &&
	    (pixel_files[current].pixel_file_id != fontptr->font_file_id);
	++current)
	;                       /* try to find file in open list */

    if (current <= nopen)       /* file already open */
    {
	if( (pxlfp = pixel_files[current].pixel_file_id) != NO_FILE )
	        fseek(pxlfp,0,0);	/* reposition to start of file */
    }
    else                        /* file not in open list */
    {
        if (nopen < MAXOPEN)    /* just add it to list */
            current = ++nopen;
	else                    /* list full -- find least used file, */
	{                       /* close it, and reuse slot for new file */
	    least_used = 1;
            for (i = 2; i <= MAXOPEN; ++i)
	        if (pixel_files[least_used].use_count >
                    pixel_files[i].use_count)
		    least_used = i;
            if (pixel_files[least_used].pixel_file_id != NO_FILE) {
                FILE *fid;
                struct font_entry *fp;

                fid = pixel_files[least_used].pixel_file_id;
                fp=hfontptr;    /* mark file as being closed in the entry */
                while (fp!=NULL && fp->font_file_id != fid) 
                        fp = fp->next;
                if (fp==NULL)
		  Fatal("Open file %x not found in font entry list.\n", fid);
                else {
                        fp->font_file_id = NULL;
#ifdef STATS
                        if (Stats)
                                fprintf(stderr, "PXL file %s closed.\n", fp->name);
#endif
                        }
 	        fclose( fid );
                }
	    current = least_used;
        }
        if ((pxlfp=BINARYOPEN(fontptr->name,"r")) == NULL) {
	    Warning("PXL file %s could not be opened",fontptr->name);
            pxlfp = NO_FILE;
            }
        else {
#ifdef STATS
            if (Stats) 
                fprintf(stderr, "PXL file %s opened.\n", fontptr->name);
#endif
            }
	pixel_files[current].pixel_file_id = pxlfp;
	pixel_files[current].use_count = 0;
    }
    pfontptr = fontptr;			/* make previous = current font */
    fontptr->font_file_id = pxlfp;	/* set file identifier */
    pixel_files[current].use_count++;	/* update reference count */
}

#ifdef PK

/*-->Pk_Get_Nyb*/
/**********************************************************************/
/*****************************  Pk_Get_Nyb  ******************************/
/**********************************************************************/

int
Pk_Get_Nyb()
{
    if (bit_weight==0) {
	input_byte = getc(pxlfp);
	bit_weight = 8;
    }
    return ((input_byte>>(bit_weight -= 4))&017);
}

/*-->Pk_Packed_Num*/
/**********************************************************************/
/*****************************  Pk_Packed_Num  ******************************/
/**********************************************************************/

int
Pk_Packed_Num()
{
    register int i, j;
    i = Pk_Get_Nyb();
    if (i==0) {
	do {j = Pk_Get_Nyb(); i++;} while (j==0);
	while (i-- > 0) 
	    j = (j<<4) + Pk_Get_Nyb();
	return (j-15+((13-dyn_f)<<4)+dyn_f);
    } else if (i <= dyn_f) return (i);
    else if (i<14) return (((i-dyn_f-1)<<4)+Pk_Get_Nyb()+dyn_f+1);
    else {
	if (i==14) rep_count = Pk_Packed_Num();
	else rep_count = 1;
	return (Pk_Packed_Num());
    }
}
#endif PK


/*-->Print_Stats*/
/**********************************************************************/
/*****************************  Print_Stats  **************************/
/**********************************************************************/

#ifdef STATS
void
Print_Stats()
{
  struct font_entry *p;

        fprintf( stderr, "Total chars   diff chars   pxl bytes\n" );
        fprintf( stderr, "      #   %%        #   %%       #   %%\n" );
        fprintf( stderr, "------- ---   ------ ---   ----- ---\n" );
        for( p=hfontptr; p!=NULL; p=p->next ) {
                fprintf( stderr, "%7d%4d", p->ncts, (100*p->ncts + Stnc/2)/Stnc );
                fprintf( stderr, "%9d%4d", p->ncdl, (100*p->ncdl + Sndc/2)/Sndc );
                fprintf( stderr, "%8d%4d", p->nbpxl, (100*p->nbpxl + Snbpxl/2)/Snbpxl );
                fprintf( stderr, "  %s\n", p->psname );
                }
        fprintf(stderr, "\nTotal number of characters typeset: %d\n", Stnc);
        fprintf(stderr, "Number of different characters downloaded: %d\n", Sndc);
        fprintf(stderr, "Number of bytes of pxl data downloaded: %d\n", Snbpxl);
        fprintf(stderr, "Optimal # of bytes of pxl data: %d\n", Sonbpx);
}

#endif STATS

#ifdef BUILTIN
/*-->PSDef*/
/**********************************************************************/
/*****************************  PSDef  *******************************/
/**********************************************************************/

char *PSDef(a)
char *a;
{
	struct BuiltIn *c;
	struct IncFile *f;
	for(c=BuiltIns; c; c=c->next)
		if(strcmp(c->TeXname,a)==0) {
		  if (PShdr) {	/* load prefix postscript code if necessary */
		    CopyFile (PSHDRFILE);
		    PShdr = FALSE;
		  }
		  if ((f = c->include) != 0 && !f->loaded) {
		    f->loaded++;
		    CopyFile (f->name);
		  }
		  return( c->Postscript );
		}
	return("<NULLFONT>");
}
#endif


/*-->ReadFontDef*/
/**********************************************************************/
/****************************  ReadFontDef  ***************************/
/**********************************************************************/

int
ReadFontDef(k)
int k;
{
    int t, i;
#ifdef PK
    int pl, cc;
#endif /* PK */
    register struct font_entry *tfontptr;/* temporary font_entry pointer   */
    register struct char_entry *tcharptr;/* temporary char_entry pointer  */
    char *direct, *tcp, *tcp1;
    int found;
    char curarea[STRSIZE];
    int cmag;
    int nmag;
    char nname[128];
    double z;

#define TfmCalc4(fp) ((int)((double)SignExtend(fp,4) * z))
#define TfmCalc3(fp) ((int)((double)SignExtend(fp,3) * z))

    if ((tfontptr = NEW(struct font_entry)) == NULL)
	Fatal("can't malloc space for font_entry");
    tfontptr->next = hfontptr;
    tfontptr->font_file_id = NULL;
    fontptr = hfontptr = tfontptr;
    for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) {
	tcharptr = &(tfontptr->ch[i]);
	tcharptr->width = 0;
	tcharptr->height = 0;
	tcharptr->xOffset= 0;
	tcharptr->yOffset = 0;
	tcharptr->where.isloaded = NOTLOADED;
	tcharptr->where.address.fileOffset = NONEXISTANT;
	tcharptr->tfmw = 0;
	tcharptr->dx = 0;
	}
    tfontptr->ncdl = 0;
#ifdef STATS
    tfontptr->nbpxl = 0;
    tfontptr->ncts = 0;
#endif

    tfontptr->k = k;
    tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */
    tfontptr->s = NoSignExtend(dvifp, 4); /* scale factor */
    tfontptr->d = NoSignExtend(dvifp, 4); /* design size */
    tfontptr->a = NoSignExtend(dvifp, 1); /* area length for font name */
    tfontptr->l = NoSignExtend(dvifp, 1); /* device length */
    GetBytes(dvifp, tfontptr->area, tfontptr->a);
    tfontptr->area[tfontptr->a] = '\0';
    GetBytes(dvifp, tfontptr->n, tfontptr->l);
    tfontptr->n[tfontptr->l] = '\0';
    tfontptr->font_space = tfontptr->s/6;
    tfontptr->font_mag = (int)((ActualFactor((int)(((float)tfontptr->s/
    			(float)tfontptr->d)*1000.0 + 0.5)) * 
#ifdef USEGLOBALMAG
			ActualFactor(mag) *
#endif
#ifdef PK
			(float)RESOLUTION
#else
  			(float)RESOLUTION * 5.0
#endif /* PK */
                           ) + 0.5);
    z = (double)tfontptr->s / (double)(1<<20);

#ifdef BUILTIN
    if( IsBuiltIn(tfontptr->n) ){
	static char ptfmname[100] = "";
	static FILE* tfmfl = NULL;
	char tfmname[100];
	int lh,bc,ec,i,nw,tfmwidth[NPXLCHARS],v;
        sprintf(tfontptr->psname, "%s.%d", tfontptr->n, tfontptr->font_mag);
	/*** Read in TFM widths from TFM file (not PXL file) ***/
	if (tfontptr->a) sprintf(tfmname, "%s/%s.tfm", tfontptr->area,
				 tfontptr->n);
	else {
	  sprintf(tfmname, "%s.tfm", tfontptr->n);
	  FindPath (TFMpath, TFMpathlen, tfmname, tfmname);
	}
	if (strcmp (tfmname, ptfmname)) {
	  if (tfmfl != NULL) fclose (tfmfl);
	  if((tfmfl=fopen(tfmname,"r"))==NULL){
		tfontptr->builtin = 0;
		tfontptr->font_file_id = NO_FILE;
		*ptfmname = '\0';
		fprintf(stderr,"Can't find TFM file %s\n",
			tfmname);
		return;
		}
	  strcpy (ptfmname, tfmname);
	}
	tfontptr->builtin = 1;
	fseek(tfmfl,2L,0);
	lh = NoSignExtend (tfmfl, 2);
	bc = NoSignExtend (tfmfl, 2);
	ec = NoSignExtend (tfmfl, 2);
	nw = NoSignExtend (tfmfl, 2);
	fseek(tfmfl,(long)(24+(lh+ec-bc+1)*4),0);
	for (i=0; i<nw; i++)
          tfmwidth[i] = TfmCalc4 (tfmfl);
	fseek(tfmfl,(long)lh*4+24,0);
	for(i=bc; i<=ec; i++) {
	  v=tfmwidth[NoSignExtend(tfmfl,1)];
	  tcharptr = &(tfontptr->ch[i]);
	  tcharptr->tfmw = v;
	  tcharptr->dx = PixRound (v, hconv);
	  getc(tfmfl);getc(tfmfl);getc(tfmfl);
	}
	return;
      }

    tfontptr->builtin=0;
#endif

    if (!findfile(PXLpath,PXLpathlen,
		       tfontptr->area,tfontptr->n,tfontptr->font_mag,
		       tfontptr->name, nname, &nmag))
     Fatal("no font %s.%d",tfontptr->n,tfontptr->font_mag);

    sprintf(tfontptr->psname, "%s.%d", tfontptr->n, tfontptr->font_mag);
    if (tfontptr != pfontptr)
	OpenFontFile();
    if ( pxlfp == NO_FILE ) {                /* allow missing pxl files */
        tfontptr->magnification = 0;
        tfontptr->designsize = 0;
        return;
        }

#ifndef PK
    if ((t = NoSignExtend(pxlfp, 4)) != PXLID)
	Fatal("PXL ID = %d, can only process PXL ID = %d files",
	      t, PXLID);
    fseek(pxlfp, -20, 2);
#else
    if ((NoSignExtend(pxlfp, 1) != PKPRE)||((t = NoSignExtend(pxlfp, 1)) != PKID))
	Fatal("PK ID = %d, can only process PK ID = %d files",
	      t, PKID);
    i = NoSignExtend(pxlfp, 1);
    for (;i>0;i--) getc(pxlfp);
    tfontptr->designsize = NoSignExtend(pxlfp, 4);
#endif /* PK */
    t = NoSignExtend(pxlfp, 4);
    if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t))
	Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d",
	        tfontptr->name, t, tfontptr->c);
#ifndef PK
    tfontptr->magnification = NoSignExtend(pxlfp, 4);
    tfontptr->designsize = NoSignExtend(pxlfp, 4);
    fseek(pxlfp, NoSignExtend(pxlfp, 4) * 4, 0);

    for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) {
	tcharptr = &(tfontptr->ch[i]);
	tcharptr->width = NoSignExtend(pxlfp, 2);
	tcharptr->height = NoSignExtend(pxlfp, 2);
	tcharptr->xOffset= SignExtend(pxlfp, 2);
	tcharptr->yOffset = SignExtend(pxlfp, 2);
	tcharptr->where.address.fileOffset = NoSignExtend(pxlfp, 4) * 4;
	tcharptr->tfmw = TfmCalc4(pxlfp);
	tcharptr->dx = PixRound(tcharptr->tfmw, hconv);
    }
#else
    t = NoSignExtend(pxlfp, 4); /* hppp */
    tfontptr->magnification = (int) (t * 72.27 *5 / 65536 + 0.5);
    if (t != NoSignExtend(pxlfp, 4)) /* vppp */
	Warning("font = \"%s\",\n-->font hppp != vppp",
	        tfontptr->name);
    while  (Skip_Specials(), input_byte != PKPOST) {
	
	dyn_f = input_byte >> 4;
	t = (input_byte >> 3)&1;
	input_byte &= 7;
	if (input_byte == 7) {
	    pl = NoSignExtend(pxlfp, 4);
	    cc = NoSignExtend(pxlfp, 4) & 0177;
	    tcharptr = &(tfontptr->ch[cc]);
	    tcharptr->tfmw = TfmCalc4(pxlfp);
	    tcharptr->dx = NoSignExtend(pxlfp, 4)>>16;
	    i = NoSignExtend(pxlfp, 4);
	    tcharptr->width = NoSignExtend(pxlfp, 4);
	    tcharptr->height = NoSignExtend(pxlfp, 4);
	    tcharptr->xOffset= SignExtend(pxlfp, 4);
	    tcharptr->yOffset = SignExtend(pxlfp, 4);
	    pl -= 28;
	}
	else if (input_byte > 3) {
	    pl = NoSignExtend(pxlfp, 2) + ((input_byte-4)<<16);
	    cc = NoSignExtend(pxlfp, 1) & 0177;
	    tcharptr = &(tfontptr->ch[cc]);
	    tcharptr->tfmw = TfmCalc3(pxlfp);
	    tcharptr->dx = NoSignExtend(pxlfp, 2);
	    tcharptr->width = NoSignExtend(pxlfp, 2);
	    tcharptr->height = NoSignExtend(pxlfp, 2);
	    tcharptr->xOffset= SignExtend(pxlfp, 2);
	    tcharptr->yOffset = SignExtend(pxlfp, 2);
	    pl -= 13;
	}
	else {
	    pl = NoSignExtend(pxlfp, 1) + ((input_byte)<<8);
	    cc = NoSignExtend(pxlfp, 1) & 0177;
	    tcharptr = &(tfontptr->ch[cc]);
	    tcharptr->tfmw = TfmCalc3(pxlfp);
	    tcharptr->dx = NoSignExtend(pxlfp, 1);
	    tcharptr->width = NoSignExtend(pxlfp, 1);
	    tcharptr->height = NoSignExtend(pxlfp, 1);
	    tcharptr->xOffset= SignExtend(pxlfp, 1);
	    tcharptr->yOffset = SignExtend(pxlfp, 1);
	    pl -= 8;
	}
	tcharptr->where.address.fileOffset = ftell(pxlfp);
	tcharptr->turn_on = t;
	tcharptr->dyn_f = dyn_f;
	fseek(pxlfp,pl,1);
    }
#endif /* PK */
}


#ifdef BUILTIN
/*-->ReadMap*/
/**********************************************************************/
/****************************  ReadMap  *******************************/
/**********************************************************************/

void
ReadMap()
{
	FILE *map;
	char TeXn[STRSIZE], PSn[STRSIZE], mapname[STRSIZE], str[STRSIZE];
	struct BuiltIn *p=0, *q;
	struct IncFile *DefaultIncFile;
	char *s;
	int count, status;
	int pathnr = 0;
	char ch;

	while ( (count = FindPath (&TFMpath[pathnr], TFMpathlen-pathnr, FONTMAP, mapname)) >= 0) {
	    pathnr += count+1;
	    if((map=fopen(mapname,"r"))==NULL)
		    Fatal("Can't open TeX->PostScript font map %s\n",mapname);
	    count = 0; DefaultIncFile = 0; s = 0;

	      while ((ch = getc(map)) != EOF) {
		count++;
		switch (ch) {
		case ' ':
		case '\t':	/* continuation line */
		  if (s==0) break;
		  if ((status = fscanf (map, " %[^\n]", str)) != 1) break;
		  strcat (s, "\n");
		  strcat (s, str);
		  continue;
		case '\n':	/* empty line */
		  continue;
		case '%':	/* comment */
		  do { ch = getc(map); } while (ch != '\n');
		  continue;
		case '#':	/* file name */
		  if ((status = fscanf (map,"%s ",str)) != 1) break;
		  DefaultIncFile = FindIncFile (TFMpath[pathnr-1],str);
		  continue;
		default:	/* font name */
		  ungetc (ch, map);
		  if ((status = fscanf (map,"%s ",TeXn)) != 1) break;
		  q = (struct BuiltIn *) malloc(sizeof (struct BuiltIn));
		  q->next = 0;
		  strcpy (q->TeXname, TeXn);
		  q->include = DefaultIncFile;
		  if (p) p->next = q;
		  else BuiltIns = q;
		  p = q;
		  if ((ch = getc(map)) == EOF) break;
		  if (ch == '#') { /* include file name */
		    if ((status = fscanf(map, "%s ", str)) != 1) break;
		    q->include = FindIncFile(TFMpath[pathnr-1],str);
		  } else ungetc(ch, map);
		  if ((status = fscanf(map, "%[^\n]", q->Postscript)) != 1)
		    break;
		  s = q->Postscript;
		  continue;
	        }
				/* here we come only after an error */
		Fatal("Syntax error in %s, line %d\n", mapname, count);
	      }
	    if(status!=EOF)
	    fclose(map);
	  }
}
#endif

#ifdef PK

/*-->Skip_SpecOAials*/
/**********************************************************************/
/****************************  Skip_Specials  *************************/
/**********************************************************************/

void
Skip_Specials()
{
    int i;
    do {
	switch (input_byte = getc(pxlfp)) {
	    case PKXXX1:
	    case PKXXX2:
	    case PKXXX3:
	    case PKXXX4:
			    i =  NoSignExtend(pxlfp, input_byte-PKXXX1+1);
			    while (--i>=0) getc(pxlfp);
			    break;
	    case PKYYY:	i = NoSignExtend(pxlfp, 4);
			    break;
	    case PKPOST:	return;
	    }
	} while (input_byte>=PKXXX1);
}
#endif


/*-->SplitPath*/
/*********************************************************************/
/********************************  SplitPath  ************************/
/*********************************************************************/

int
SplitPath(path)
char **path;
{
    char *area, *tmp;
    int pathlen = 0;
    strcpy ( area = malloc(strlen(*path)+1), *path);
    do {
	path[pathlen++] = area;
	tmp = index (area, ':');
	if (tmp) {
	    *tmp = '\0';
	    area = tmp+1;
	}
    } while (tmp && *area);
    return pathlen;
}
#ifdef PK

/*-->Unpack_Raster*/
/**********************************************************************/
/*****************************  Unpack_Raster  ******************************/
/**********************************************************************/

int gpower[] = {00,01,03,07,017,037,077,0177,0377};

void
Unpack_Raster(ptr)
register struct char_entry *ptr;
{
    char row[1000];
    register int ww, w, h_bit, count, r_l, r_p;
    register char *pr, turn_on;
    bit_weight = 0;
    turn_on = ptr->turn_on;
    pr = ptr->where.address.pixptr;
    r_l = ptr->height;
    h_bit = ptr->width;
    rep_count = 0;
    ww = 8; w = 0; r_p = 1;
    while (r_l > 0) {
	count = Pk_Packed_Num();
	while (count > 0) {
	    if ((count<ww) && (count<h_bit)) {
		if (turn_on) w |= gpower[ww] - gpower[ww-count];
		h_bit -= count; ww -= count; count = 0;
	    } else if ((count>=h_bit) && (h_bit<=ww)) {
		if (turn_on) w |= gpower[ww] - gpower[ww-h_bit];
		row[r_p] = w;
		r_l -= (++rep_count);
		while (rep_count-- > 0) {
		    for (w=1; w<=r_p;) *pr++ = row[w++];
		}
		rep_count = 0; r_p = 1; w = 0; ww = 8;
		count -= h_bit; h_bit = ptr->width;
	    } else {
		if (turn_on) w |= gpower[ww];
		row[r_p++] = w;
		w = 0; count -= ww; h_bit -= ww;
		ww = 8;
	    }
	}
	turn_on = ! turn_on;
    }
}
		    

#endif /* PK */


