/* $Header:_font.c 12.0$ */
/* $ACIS:_font.c 12.0$ */
/* $Source: /ibm/acis/usr/src/usr.lib/libaed/RCS/_font.c,v $ */

#ifndef lint
static char *rcsid = "$Header:_font.c 12.0$";
#endif

#include "whim.h"
#define TERM(F,S) {fprintf(stderr,F,S); *f_id = 0; return;}
VI_GetFont(name,f_id)
  char *name;			    /* name of font file */
  INT16 *f_id;
  begin
#include "whimdcl.h"
    INT16 namelen;	     /* length of name */
    INT16 i;		     /* string counter */
    fontdesc *font;   /* font in the font chain */
    INT16 found;		     /* font found */
    extern char *malloc();
    char *mtest;	/* test return of malloc  */

    INT_PURE fontfile;	     /* font file */
    chardesc *defn;   /* char definition */
    INT16 code; 	     /* character codepoint */
    INT16 len;		     /* length of definition (words) */
    unsigned INT32 totlen;    /* length of font */
    INT32 lloc; 	     /* offset for lseek */

    if (saving) { JOURNL(V_GETFONT);
		  strjour(name);}

    /* look through font list for the font name */
    font = fonts;
    found = 0;
    while (found == 0 && font != NULL) begin
      if (strcmp(font->name,name) == 0)
	found = 1;
	else font = font->nfont;
    end;

    if (found != 0) { *f_id = font->id;
		      return;
		    }

    /* a new font */

    /* open the font file */
    fontfile = open(name,BREAD);
    if (fontfile == -1) { fprintf(stderr,"Error opening file %s\n",name);
			  *f_id = 0;
			  return;
			}

#ifdef DEBUG
printf("GetFont: font exists and file opened\n");
#endif
    /* font exists.  create a descriptor for it */
    font = (fontdesc *) (mtest = malloc(sizeof(fontdesc)));
    if (mtest == NULL) TERM("No room in heap.  Font %s fails.\n",name);

    /* make a copy of the file name */
    font->name = (char *) (mtest =  malloc(strlen(name)+1));
    if (mtest == NULL) TERM("No room in heap.  Font %s fails.\n",name);
    strcpy(font->name,name);

    /* give the font an id */
    font->id = nextfontid++;

    /* start all chars nil.  undefined chars will remain so */
    for (i = 0; i < 256; i++) begin
      font->index[i] = NULL;
    end;

    /* get the total length of the file, two words */
    read(fontfile,&totlen,4);

    /* seek past the index -- length word, then 256 entries, 16 each */
    lloc = 4+256*16;
    lseek(fontfile,lloc,0);

    totlen-= 4+256*16;

    while (totlen > 0) begin
      /* get character codepoint */
      read(fontfile,&code,2);
      totlen-= 2;

      /* get length of definition */
      read(fontfile,&len,2);
      totlen-= 2;

      /* allocate character descriptor */
      defn = (chardesc *) (mtest = malloc(sizeof(chardesc)));
      if (mtest == NULL) TERM("No room in heap.  Font %s fails.\n",name);

      /* allocate array to hold char defn */
      defn->defn = (unsigned INT16 *) (mtest = malloc(len*2));
      if (mtest == NULL) TERM("No room in heap.  Font %s fails.\n",name);
      defn->len = len;

      /* copy defn from file to location */
      read(fontfile,defn->defn,len*2);
      totlen-= len*2;

      /* save defn in font structure */

      font->index[code] = defn;
    end;

    /* add font to head of font list */
    font->nfont = fonts;
    fonts = font;

    /* return id of new font */
    *f_id = font->id;
    return;
  end

VI_DropFont(fontid)
INT16 fontid;

  begin
#include "whimdcl.h"
  INT16 i;
  fontdesc *font, *lastfont;	/* for searching with */
  INT16 found;
  char *fntname;

    if (saving) { font = fonts;
		  found = 0;
		  fntname = "notfound";
		  while (found == 0 && font != NULL)
		      { if (font->id == fontid)
			  { found = 1;
			    fntname = font->name;
			  }
			  else font = font->nfont;
		      }
		  JOURNL(V_DROP);
		  strjour(fntname);
		}

  if (fonts==NULL) return(TRUE);	/* want to save the call before this */
					/* test for debug purposes	     */

  font = fonts; 	/* start looking at root */
  lastfont = NULL;

  while (font->id != fontid)  /* look thru list for font to drop */
	{ if (font->nfont == NULL) return(TRUE);  /* EOList, return error */
	  lastfont = font;    /* save for list maintenance	*/
	  font = font->nfont; /* progress thru the list 	*/
	}

  /* By here, 'font' points to the font to drop, and 'lastfont' points to
     the font which points to the font to drop				*/

  for (i=0; i<256; i++) if(font->index[i] != NULL)
      { if (font->index[i]->defn != NULL) { free(font->index[i]->defn);
					    font->index[i]->defn = NULL;
					  }
	free(font->index[i]);
	font->index[i] = NULL;
      }
  if (lastfont == NULL) fonts = NULL;
     else lastfont->nfont = font->nfont;   /* take font out of list	 */
  free(font->name);
  font->name = NULL;
  free(font);			   /* free does its own error checking	*/
  font = NULL;
  return(FALSE);		   /* no errors detected		*/
  end
