/*----------------------------------------------------------------------*/
/* This routine prints a char from one of my fonts, it has cacheing 	*/
/* for the char data, which could be extended to bitmap cacheing 	*/
/*----------------------------------------------------------------------*/
#include "all.h"
#include "core.h"
#include "color.h"
extern struct gmodel g;
#include "mygraph.h"
#define true (!false)
#define false 0
#ifdef BIGINDIAN
#define BYTE0 1
#define BYTE1 0
#else
#define BYTE0 0
#define BYTE1 1
#endif

int font_file_vector(int ff,char *filename);
int draw_char_pcode(char *s);
char *fontdir(char *s);
int my_load_font(int ff);
double frx(char **s);
unsigned char my_name[80];
char *my_code[80];
int my_ref[80];
char *my_buff;
int my_font[80];
int my_pnt[257];
int my_curfont;
extern double font_lwidth;
int char_plen(char *s);
int get_char_pcode(int ff, int cc, char **pp);
my_char(int ff, int cc)
{
	char *pp;
	get_char_pcode(ff,cc,&pp);
	draw_char_pcode(pp);
}
get_char_pcode(int ff, int cc, char **pp)
{
	int i,plen,mi,minref;

/* y:	Is char in font cache, if so draw it, inc ref */
	/*  should use *memchr(s,c,n)  */
	for (i=1;i<80;i++) {
		if (my_name[i]==cc) {
			if (my_font[i]==ff) {
				my_ref[i]++;
				*pp = my_code[i];
				return;
			}
		}
	}

/* x:	Is that font currently loaded, if so put in cache at least used, goto y */
	minref = 30000;
	mi = 0;
	if (my_curfont!=ff) my_load_font(ff);
	/* Find least used cache character */
	for (i=1;i<80;i++)  {
		if (my_ref[i]<minref) {minref=my_ref[i]; mi = i;}
	}
	if (mi==0) mi=1;
	plen = char_plen(my_buff+my_pnt[cc]);
	if (my_code[mi]==0) my_code[mi] = myallocz(plen+1);
	else		{
	/*	my_code[mi] = realloc(my_code[mi],plen+1); */
		myfree(my_code[mi]);
		my_code[mi] = myalloc((plen+1));
	}
	if (my_code[mi]==0) gprint("Memory allocation failure, in myfont.c \n");
	memcpy(my_code[mi],my_buff+my_pnt[cc],plen+1);
	*pp = my_code[mi];
	my_name[mi] = cc;
	my_ref[mi] = 1;
	my_font[mi] = ff;
}
/* free up memory used by vector font */
freeavec()
{
	if (my_buff == NULL) return;
	myfree(my_buff);
	my_buff = 0;
	my_curfont = 0;
}
char *gledir(char *s);
my_load_font(int ff)
{
	char vector_file[60];
	int i;
	FILE *fin;
	font_file_vector(ff,vector_file);
	fin = fopen(fontdir(vector_file),READ_BIN);
	if (fin==0) {
		gprint("(Warning) can't find vector file {%s} replacing it.\n",fontdir(vector_file));
		font_replace_vector(ff);
		font_file_vector(ff,vector_file);
		fin = fopen(fontdir(vector_file),READ_BIN);
		if (fin==NULL) gle_abort("Font vector texcmr.fve not found\n");
	}
	fread(my_pnt,sizeof(i),256,fin);
	/* gprint("Size of rest of font %d \n",my_pnt[0]); */
	if (my_buff==0) my_buff = myallocz(10 + my_pnt[0]);
	else 		{
		myfree(my_buff);
		my_buff = myallocz(10 + my_pnt[0]);
	}
	if (my_buff==0) gprint("Memory allocation failure MY_BUFF , in myfont.c \n");
	fread(my_buff,1,my_pnt[0],fin);
	fclose(fin);
	my_curfont = ff;
}
int frxi(char **s);
char_plen(char *s)
{
	char *savelen;
	savelen = s;
	while (*s!=15) {
	  switch (*s++) {
	    case 1:
	    case 2:
		frxi(&s); frxi(&s);
		break;
	    case 3:
		frxi(&s); frxi(&s);
		frxi(&s); frxi(&s);
		frxi(&s); frxi(&s);
		break;
	    case 4:
	    case 5:
	    case 6:
	    case 7:
	    case 8:
		break;
	    case 0: /* char does not exist */
		goto abort;
	    default:
		gprint("Error in mychar pcode %d \n",*s++);
		goto abort;
	  }

	}
abort:
	return s-savelen;
}
int draw_char_pcode(char *s)
{
	static double cx,cy,ox,oy,x1,y1,x2,y2;
	char *savelen;
	double old_lwidth;
	int old_path,old_join;
	int32 old_color;

	g_get_path(&old_path);
	g_get_color(&old_color);
	g_set_fill(old_color);
	g_get_line_width(&old_lwidth);
	g_set_line_width(font_lwidth);
	g_get_line_join(&old_join);
	g_set_line_join(1);	/* use rounded lines to avoid ucky peeks */

	g_get_xy(&ox,&oy);
	savelen = s;
	if (!old_path) {
		g_set_path(true);
		g_newpath();
	}
	while (*s!=15) {
	  switch (*s++) {
	    case 1:
		cx = ox + frx(&s); cy = oy + frx(&s);
		g_move(cx,cy);
		break;
	    case 2:
		cx = cx + frx(&s); cy = cy + frx(&s);
		g_line(cx,cy);
		break;
	    case 3:
		cx = cx + frx(&s); cy = cy + frx(&s);
		x1 = cx; y1 = cy;
		cx = cx + frx(&s); cy = cy + frx(&s);
		x2 = cx; y2 = cy;
		cx = cx + frx(&s); cy = cy + frx(&s);
		g_bezier(x1,y1,x2,y2,cx,cy);
		break;
	    case 4:
		g_closepath();
		break;
	    case 5:
		if (!old_path) 	g_fill();
		break;
	    case 6:
		g_stroke();
		break;
	    case 7:
		g_gsave();
		g_set_fill(COLOR_WHITE);
		g_fill();
		g_grestore();
		break;
	    case 8:
		g_set_line_width(frx(&s));
		break;
	    case 0:         /* no such char in this font */
		goto abort;
	    default:
		gprint("Error in mychar pcode %d \n",*s++);
		goto abort;
	  }

	}
abort:	if (!old_path) g_set_path(old_path);
	g_set_line_join(old_join);
	g_set_line_width(old_lwidth);
	g_set_color(old_color);
	return s-savelen;
}
double frx(char **s)
{
	static union {char a[2];short b;} both;
	static int i;

	if (g.fontsz==0) {
		gprint("Font size is zero ***\n");
		g.fontsz = 1;
	}
	i = *(*s)++;
	if (i==127) {
		both.a[0] = (*(*s)++);
		both.a[1] = (*(*s)++);
		if (1==2) printf("bothb %d \n",both.b);
		return (g.fontsz*both.b)/1000.0;
	} else {
	        if (i>127) i = -(256-i);
		if (1==2) printf("ii %d \n",i);
		return (g.fontsz*i)/1000.0;
	}
}
frxi(char **s)
{
	static union {char a[2];short b;} both;
	static int i;

	i = *(*s)++;
	if (i==127) {
		both.a[0] = (*(*s)++);
		both.a[1] = (*(*s)++);
		if (1==2) printf("both %d \n",both.b);
		return (both.b);
	} else {
	        if (i>127) i = -(256-i);
		if (1==2) printf("i %d \n",i);
		return i;
	}
}


















