 /*
  * Khoros: $Id: font_3D.c,v 1.1 1991/05/10 15:56:56 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: font_3D.c,v 1.1 1991/05/10 15:56:56 khoros Exp $";
#endif

 /*
  * $Log: font_3D.c,v $
 * Revision 1.1  1991/05/10  15:56:56  khoros
 * Initial revision
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 *
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "X3D.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: font_3D.c 
   >>>>               
   >>>>   description: Font  Utilities
   >>>>              
   >>>>      routines:
   >>>>			X3D_init_font()			      <<<<
   >>>>			_X3D_copy_character()		      <<<<
   >>>>			_X3D_get_font()		      	      <<<<
   >>>>			X3D_set_font()		      	      <<<<
   >>>>			_X3D_valid_fontname()	      	      <<<<
   >>>>			X3D_inquire_fonts()	      	      <<<<
   >>>>                                                       <<<<
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

/*
 *  Possible font sets.  Initialize font structure to NULL since none
 *  of them have been initialized.  The font is only initialized
 *  when the application requests for that specific font.
 */
X3DFont   *fonts = NULL;


/************************************************************
*
*  MODULE NAME: X3D_init_font
*
*      PURPOSE: reads a font description file, and sets up
*		the X3DFont structure for each character
*		described there, so that characters can be
*		drawn later using that font structure
*
*
*        INPUT: fontname - name to assign to this font
*		filename - name of the Khoros font file
*
*       OUTPUT: creates & sets an X3DFont structure filled appropriately
*
*    CALLED BY: application program
*
*   WRITTEN BY: Danielle Argiro and Mark Young
*
*************************************************************/


X3DFont *X3D_init_font(fontname, filename)

char	*fontname, *filename;
{
	FILE	*file;
	char	buffer[80];
	char	letter, comm, last_comm, key;
	int	i, j, k, xloc, yloc, last_xloc, last_yloc;
	int	xmin, xmax, ymin, ymax;

	int	size;
	Coord   points[350];

	X3DFont *font;

	file = fopen(filename, "r");
	if (file == NULL)
	{
	    (void) fprintf(stderr, "X3D_init_font: ");
	    (void) fprintf(stderr, "Unable to open font description file %s\n",
			   filename);
	    return(NULL);
	}


	if (!(font = (X3DFont *) malloc(sizeof(X3DFont))))
	{
            (void) fprintf(stderr, "X3D_init_font: ");
            (void) fprintf(stderr, "out of temporary space.\n");
            return(NULL);

	}
	font->fontname = VStrcpy(fontname);

	i = 0; j = 0;
	fgets(buffer, 80, file);
	if (sscanf(buffer, "%*[ \t]%c%c%*[ \t]%d%*[ \t]%d\n",
		         &key, &last_comm, &last_xloc, &last_yloc) != 4) 
	{
	      (void) fprintf(stderr, "X3D_init_font: ");
	      (void) fprintf(stderr,"Error in read, description file ");
	      (void) fprintf(stderr,"%s, line %d\n", filename, (i + 1));
	      free(font);
	      return(NULL);
	}
	xmin = xmax = last_xloc;
	ymin = ymax = last_yloc;

	size = 0;
	font->character[0].ch = key;
	while (!feof(file))
	{
	   fgets(buffer,80,file);
	   if (sscanf(buffer, "%*[ \t]%c%c%*[ \t]%d%*[ \t]%d\n",
		         &letter, &comm, &xloc, &yloc) != 4) 
	   {
	      (void) fprintf(stderr, "X3D_init_font: ");
	      (void) fprintf(stderr,"Error in read, description file ");
	      (void) fprintf(stderr,"%s, line %d\n", filename,i+1);
	      free(font);
	      return(NULL);
	   }

	   /*
	    *  Find the max and min for x & y.
	    */
	   if (xmax < xloc)
	      xmax = xloc;
	   else if (xmin > xloc)
	      xmin = xloc;

	   if (ymax < yloc)
	      ymax = yloc;
	   else if (ymin > yloc)
	     ymin = yloc;

	   /*
	    * Check to see if we have are starting a new character.
	    */
	   if (key != letter)
	   {
	      /*
	       * If the number of vectors gotten for the last character
	       * were greater than zero, then get the last character.
	       */
	      if (size != 0)
	      {
		 if (last_comm != 'U')
		 {
		    size++;
		    points[j].x = last_xloc;
		    points[j].y = last_yloc;
		    points[j].z = 0.0;
	 	 }

		 /*
		  * Increment i to the next character.
		  */
		_X3D_copy_character(&(font->character[i]), points, size);
		i++;
	      }

	      /*
	       *  Set the number of vector and the character we are trying to
	       *  draw.
	       */
	      size = j = 0;
	      font->character[i].ch = key = letter;
	   }
	   else if ((last_comm != 'U') || (comm != 'U'))
	   {
	      size++;
	      points[j].x = last_xloc;
	      points[j].y = last_yloc;
	      points[j].z = 0.0;
	      j++;

	      if ((comm == 'D') && (last_comm == 'D'))
	      {
	        size++;
	         points[j].x = last_xloc;
	         points[j].y = last_yloc;
	         points[j].z = 0.0;
	         j++;
	      }
	   }
	   last_comm = comm;
	   last_xloc = xloc;
	   last_yloc = yloc;
	}
	fclose(file);

	font->wc_min.x = xmin; font->wc_max.x = xmax;
	font->wc_min.y = ymin; font->wc_max.y = ymax;
	font->wc_min.z = 0.0;  font->wc_max.z = 1.0;
	font->num      = i;

	if (fonts == NULL)
	{
	   fonts = font;
	   font->next = NULL;
	}
	else
	{
	   font->next = fonts;
	   fonts = font;
	}
	return(font);
}

/************************************************************
*
*  MODULE NAME: _X3D_copy_character
*
*      PURPOSE: copies points into the character array
*
*        INPUT: character  - pointer to character structure
*		points  - array of world coordinate points describing character
*			  (vector strokes that describe the character)
*		size   -  number  of points in character
*
*       OUTPUT: mallocs and fills out the character structure
*
*    CALLED BY: application program
*
*   WRITTEN BY:	Mark Young
*
*************************************************************/


_X3D_copy_character(character, points, size)

X3DCharacter *character;
Coord	     points[];
int	     size;
{
	int	i;

	if (!(character->points = (Coord *) malloc((unsigned) sizeof(Coord) * 
	      size)))
	{
	   character->num = 0;
	   return;
	}

	character->num = size;
	for (i = 0; i < size; i++)
	   character->points[i] = points[i];
}




/************************************************************
*
*  MODULE NAME: _X3D_get_font
*
*      PURPOSE: retrieves the X3DFont structure associated with a 
*		certain font name
*
*        INPUT: fontname - name of the font
*
*       OUTPUT: X3D_font structure retrieved, or NULL on failure
*
*    CALLED BY: 
*
*   WRITTEN BY: Mark Young
*
*************************************************************/


X3DFont *_X3D_get_font (fontname)

char	*fontname;
{
        X3DFont         *temp;

	if (fonts == NULL)
	{
	   return(NULL);
	}

	temp = fonts;
	while (temp->next != NULL && (strcmp(temp->fontname, fontname) != NULL))
	    temp = temp->next;
	

	if (strcmp(temp->fontname, fontname) == NULL)
	    return(temp);
	else
	    return(NULL);
}


/************************************************************
*
*  MODULE NAME: X3D_set_font
*
*      PURPOSE: Sets the font to be used when drawing text
*
*        INPUT: id - xvgraphics id
*		fontname - name of the desired font
*
*       OUTPUT: none
*
*    CALLED BY: application program
*
*   WRITTEN BY: Mark Young
*
*************************************************************/


X3D_set_font (id, fontname)

int     id;
char	*fontname;
{
	char		*file;
        X3DGraphics     *graphics, *text;
	X3DFont		*_X3D_get_font(), *X3D_init_font();


        if (!(graphics = _X3D_get_graphics(id)))
        {
           fprintf (stderr,"X3D_set_font:");
           fprintf (stderr,"\t unknown graphics id %d\n",id);
           return;
        }

	if ((graphics->font = _X3D_get_font(fontname)) == NULL)
	{
	   file = vfullpath(fontname, FONTDIR, NULL);

	   graphics->font = X3D_init_font(fontname, file);
	   free(file);
	}

	if (!(text = _X3D_get_graphics(TEXT_ID)))
	{
	   X3D_init_graphics(TEXT_ID, X2D);
	}
}



/************************************************************
*
*  MODULE NAME: _X3D_valid_fontname
*
*      PURPOSE: sees if filename given has ".vec" on the end, as is
*		the convention for Khoros font files.  
*
*        INPUT: filename - Khoros font file
*
*       OUTPUT: If filename has ".vec" on the end, returns filename 
*		without it.  If filename doesn't have ".vec" on the
*		end, returns NULL
*
*    CALLED BY: application program
*
*   WRITTEN BY: Mike Lang & Mark Young
*
*************************************************************/

char  *_X3D_valid_fontname(filename)

char	*filename;
{
	char *string;

	if ((string = strrchr(filename,'.')) != NULL)
	{
	   if (strcmp(string,".vec") == NULL)
	   {
	      string[0] = '\0';
	      return(filename);
	   }
	   else
	      return(NULL);
	}
	else
	   return(NULL);
}


/************************************************************
*
*  MODULE NAME: X3D_inquire_fonts
*
*      PURPOSE: inquire as to what fonts are currently available,
*		returns an array of strings naming available fonts
*
*        INPUT: none
*
*       OUTPUT: returns a pointer to an array of char describing 
*		the available fonts, and the number of fonts
*
*    CALLED BY: application program
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/

#define MAXFONTS 20

char **X3D_inquire_fonts(fontnum)

int	*fontnum;
{
	DIR *dir;
	int i = 0;
	vdirect *d_ent;
	char *dirname, *_X3D_valid_fontname();
	caddr_t *list;

	list = (caddr_t *) malloc(sizeof(caddr_t)*MAXFONTS);
	dirname = vfullpath(FONTDIR, NULL, NULL);

	if((dir = opendir(dirname)) == NULL)
	{
		/* error */
		return(NULL);
	}

	while( ((d_ent = readdir(dir)) != NULL) && (i < MAXFONTS) )
	{
	    if (_X3D_valid_fontname(d_ent->d_name) != NULL)
	       list[i++] = (caddr_t)VStrcpy(d_ent->d_name);
	}
	list[i] = NULL;

	*fontnum = i;
	return((char **)list);
}
