/*---------------------------------------------------------------------
 
      Modified from et15.c, et24m.c, et24k.c, tran.c of
           xcin-2.1b/big5font package.
                      by Tung-Han Hsieh

---------------------------------------------------------------------*/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <dirent.h>

#define VERSION     "0.2"
#define TMPFILE     "et2bdf-0.1.tmp"


typedef struct {
	char  *head;
	char  *fn1, *fn2, *fn3, *fn4;
} FontDef;


int	  debug;
char	  etpath[128];
int     (*outfunc)(FILE *fp, FILE *fw, int count, int ofs);
FontDef  *FD;


int ser_b5(u_char *ch, u_char *tt);
int et15_out(FILE *fp, FILE *fw, int count, int ofs);
int et24_out(FILE *fp, FILE *fw, int count, int ofs);
void ChineseFonts(void);
int vga8x15_out(FILE *fp, FILE *fw, int count, int ofs);
int vga12x24_out(FILE *fp, FILE *fw, int count, int ofs);
void EnglishFonts(void);

int   Input(int argc, char *argv[]);
FILE *OpenFile(char *fn, char *pw, char *md, char *err_str);


/*---------------------------------------------------------------------

                             Font Definitions.

---------------------------------------------------------------------*/

FontDef et15 = {
	"STARTFONT 2.1\n"
	"COMMENT 16x15 Font\n"
	"FONT et15\n"
	"SIZE 16 100 100\n"
	"FONTBOUNDINGBOX 16 15 0 -1\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 14\n"
	"FONT_DESCENT 1\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et15\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 16\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.15",
	"stdfont.15",
	"spcfsupp.15",
	"usrfont.15m"
};

FontDef et24m = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24m\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24m\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24",
	"spcfsupp.24",
	"usrfont.24m"
};

FontDef et24k = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24k\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24k\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24k",
	"spcfsupp.24",
	"usrfont.24k"
};

FontDef et24b = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24b\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24b\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24b",
	"spcfsupp.24",
	"usrfont.24b"
};

FontDef et24r = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24r\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24r\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24r",
	"spcfsupp.24",
	"usrfont.24r"
};

FontDef et24s = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24s\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24s\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24s",
	"spcfsupp.24",
	"usrfont.24s"
};

FontDef et24l = {
	"STARTFONT 2.1\n"
	"COMMENT 24x24 Font\n"
	"FONT et24l\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 24 24 0 -2\n"
	"STARTPROPERTIES 12\n"
	"FONT_ASCENT 22\n"
	"FONT_DESCENT 2\n"
	"DEFAULT_CHAR 41280\n"
	"COPYRIGHT \"Eten\"\n"
	"POINT_SIZE 240\n"
	"FONT \"et24l\"\n"
	"WEIGHT 10\n"
	"RESOLUTION 103\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"X_HEIGHT 4294967295\n"
	"QUAD_WIDTH 24\n"
	"ENDPROPERTIES\n"
	"CHARS",

	"spcfont.24",
	"stdfont.24l",
	"spcfsupp.24",
	"usrfont.24l"
};

FontDef vga8x15 = {
	"STARTFONT 2.1\n"
	"COMMENT X\n"
	"FONT vga8x15\n"
	"SIZE 15 100 100\n"
	"FONTBOUNDINGBOX 8 15 0 -1\n"
	"STARTPROPERTIES 19\n"
	"FONTNAME_REGISTRY \"\"\n"
	"FOUNDRY \"Eten\"\n"
	"FAMILY_NAME \"Fixed\"\n"
	"WEIGHT_NAME \"Medium\"\n"
	"SLANT \"R\"\n"
	"SETWIDTH_NAME \"Normal\"\n"
	"ADD_STYLE_NAME \"\"\n"
	"PIXEL_SIZE 15\n"
	"POINT_SIZE 170\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"SPACING \"C\"\n"
	"AVERAGE_WIDTH 80\n"
	"CHARSET_REGISTRY \"ISO8859\"\n"
	"CHARSET_ENCODING \"1\"\n"
	"DEFAULT_CHAR 32\n"
	"FONT_DESCENT 1\n"
	"FONT_ASCENT 14\n"
	"COPYRIGHT \"Eten\"\n"
	"ENDPROPERTIES\n"
	"CHARS 256\n",

	"ascfont.15",
	NULL,
	NULL,
	NULL
};

FontDef vga12x24 = {
	"STARTFONT 2.1\n"
	"COMMENT X\n"
	"FONT vga12x24\n"
	"SIZE 24 100 100\n"
	"FONTBOUNDINGBOX 12 24 0 -2\n"
	"STARTPROPERTIES 19\n"
	"FONTNAME_REGISTRY \"\"\n"
	"FOUNDRY \"Eten\"\n"
	"FAMILY_NAME \"Fixed\"\n"
	"WEIGHT_NAME \"Medium\"\n"
	"SLANT \"R\"\n"
	"SETWIDTH_NAME \"Normal\"\n"
	"ADD_STYLE_NAME \"\"\n"
	"PIXEL_SIZE 24\n"
	"POINT_SIZE 170\n"
	"RESOLUTION_X 100\n"
	"RESOLUTION_Y 100\n"
	"SPACING \"C\"\n"
	"AVERAGE_WIDTH 120\n"
	"CHARSET_REGISTRY \"ISO8859\"\n"
	"CHARSET_ENCODING \"1\"\n"
	"DEFAULT_CHAR 32\n"
	"FONT_DESCENT 2\n"
	"FONT_ASCENT 22\n"
	"COPYRIGHT \"Eten\"\n"
	"ENDPROPERTIES\n"
	"CHARS 256\n",

	"ascfont.24",
	NULL,
	NULL,
	NULL
};


/*---------------------------------------------------------------------

			Font Special functions

---------------------------------------------------------------------*/

int ser_b5(u_char *ch, u_char *tt)
{
        u_short  q, r, ofs, oofs;
	int      ok=1;

        tt[2] = 0;
        ofs = ((u_short)*ch<<8)|*(ch+1);
        oofs = ofs;

        if(ofs == 0)
                *tt = *(tt+1) = 0;
        else if(ofs < 0x8400) {
                ofs -= 0x8001;
                q = ofs/157; r = ofs%157;
                if(r < 0x3f)
                        *(tt+1) = r + 0x40;
                else
                        *(tt+1) = (r - 63) + 0xa1;
                if(q < 94)
                        *tt = q + 0xc6;
                else {
                        fprintf(stderr, "#error ofs:%x\n", ofs);
                	ok = 0;
		}
        }
        else if(ofs < 0x8800) {
                ofs -= 0x8400;
                if(ofs >= 5401) 
			ofs += 408; 	/* useless */
                q = ofs / 157; 
		r = ofs % 157;
                if(r < 63)
                        *(tt+1) = r + 0x40;
                else
                        *(tt+1) = (r-63) + 0xa1;

                if(q < 94)
                        *tt = q + 0xa1;
                else {
                        fprintf(stderr, "error ofs:%x\n", ofs);
                	ok = 0;
		}
        }
        else if(ofs >= 0xe000) {
                ofs -= 0xe000;
                q = ofs/157;
		r = ofs%157;
                if(r < 63)
                        *(tt+1) = r + 0x40;
                else
                        *(tt+1) = (r-63)+0xa1;

                if(q < 5)
                        *tt = q + 0xfa;
                else if(q < 24)
                        *tt = q + 0x8e - 5;
                else if(q < 37)
                        *tt = q + 0x81 - 24;
                else {
                        fprintf(stderr, "#error ofs:%x\n", ofs);
                	ok = 0;
		}
        }
	else {
	        ofs-=0x8800;
	        if(ofs >= 5401) 
			ofs += 408;
	        q = ofs / 157; 
		r = ofs % 157;
	        if(r < 63)
	                *(tt+1) = r + 0x40;
	        else
	                *(tt+1) = (r-63) + 0xa1;

	        if(q < 94)
	                *tt = q + 0xa4;
	        else {
	                fprintf(stderr, "!error oofs:%x\n", oofs);
			ok = 0;
		}
	}
	return  ok;
}

int et15_out(FILE *fp, FILE *fw, int count, int ofs)
{
	u_char  tt[3], uu[3], bf[15][2];
	int     v, i;

	if((v=fread(bf,1,sizeof(bf),fp)) != sizeof(bf)) 
		return  0; 

	tt[0] = ofs >> 8;
	tt[1] = ofs & 255;
	if(!ser_b5(tt, uu))
		return  0;

	fprintf(fw, "STARTCHAR %d\n", count);
	fprintf(fw, "ENCODING %d\n", (u_short)uu[0]<<8 | uu[1]);
        fprintf(fw, "SWIDTH 640 0\n");
        fprintf(fw, "DWIDTH 16 0\n");
        fprintf(fw, "BBX 16 15 0 -1\n");
	fprintf(fw, "BITMAP\n");
	for(i=0; i<15; i++) {
		v = ( (u_int)bf[i][0] << 8 ) | bf[i][1];
		fprintf(fw,"%04x\n", v);
	}
	fprintf(fw, "ENDCHAR\n");

	return  1;
}

int et24_out(FILE *fp, FILE *fw, int count, int ofs)
{
        u_char  tt[3], uu[3], bf[24][3];
        int     v, i;

        if((v=fread(bf, 1, sizeof(bf),fp)) != sizeof(bf))
                return  0;

        tt[0] = ofs >> 8;
        tt[1] = ofs & 255;
        if(!ser_b5(tt, uu))
		return  0;

        fprintf(fw, "STARTCHAR %d\n", count);
        fprintf(fw, "ENCODING %d\n", (u_short)uu[0]<<8 | uu[1]);
        fprintf(fw, "SWIDTH 960 0\n" );
        fprintf(fw, "DWIDTH 24 0\n" );
        fprintf(fw, "BBX 24 24 0 -2\n" );
        fprintf(fw, "BITMAP\n");
        for(i=0; i<24; i++) {
                v = (((u_int)bf[i][0]<<16) | ((u_int)bf[i][1]<<8)) | bf[i][2];
                fprintf( fw, "%06x\n", v );
        }
        fprintf(fw, "ENDCHAR\n");

	return  1;
}


void ChineseFonts(void)
{
	FILE  *fr1, *fr2, *fw;
	int    count, ofs;

/* Initialize */
	fw = OpenFile(TMPFILE, NULL, "wt", "Cannot open tmp file in current directory.");

/* Read the 1-st ET-file & out to tmpfile */
	fr1 = OpenFile(FD->fn1, etpath, "rt", NULL);
	ofs=0x8400; 
	count=0;
	while(!feof(fr1)) {
		if(outfunc(fr1, fw, count, ofs)) {
			ofs++; 
			count++;
		}
	}
	fclose(fr1);

/* Read the 2-nd, 3-rd ET-files & out to tmpfile */
	fr1 = OpenFile(FD->fn2, etpath, "rt", NULL);
	ofs = 0x8800;
	while(!feof(fr1)) {
		if(outfunc(fr1, fw, count, ofs)) {
			ofs++; 
			count++;
		}
		if(ofs == 0x9d19) {
			fr2 = OpenFile(FD->fn3, etpath, "rt", NULL);
			ofs = 0x8001 + 0x3f;
			while(!feof(fr2)) {
				if(outfunc(fr2, fw, count, ofs)) {
					ofs++; 
					count++;
				}
			}
			ofs=0x9d19;
			fclose(fr2);
		}
	}
	fclose(fr1);

/* Read the 4-th ET-file & out to tmpfile */
	fr1 = OpenFile(FD->fn4, etpath, "rt", NULL);
	fseek(fr1, 0x100L, SEEK_SET);
	ofs = 0xe000;
	while(!feof(fr1)) {
		fseek(fr1, 4L, SEEK_CUR);
		if(outfunc(fr1, fw, count, ofs)) {
			ofs++; 
			count++;
		}
	}
	fprintf(fw, "ENDFONT\n");
	fclose(fr1);
	fclose(fw);

/* Read the tmpfile & out to stdout */
	fprintf(stdout, "%s %d\n", FD->head, count);
	fw = OpenFile(TMPFILE, NULL, "rt", "Cannot read the tmpfile.");
	while((ofs=fgetc(fw)) != EOF) 
		fputc(ofs, stdout);
	fclose(fw);

	if(!debug)
		remove(TMPFILE);
}


int vga8x15_out(FILE *fp, FILE *fw, int count, int ofs)
{
	u_char  tt[2];
	int	i;

	fprintf(fw, "STARTCHAR C%03d\n", count);
	fprintf(fw, "ENCODING %d\n", count);
	fprintf(fw, "SWIDTH 508 0\n");
	fprintf(fw, "DWIDTH 8 0\n");
	fprintf(fw, "BBX 8 15 0 -1\n");
	fprintf(fw, "BITMAP\n");

	for(i=0; i<15; i++) {
		fread(tt, 1, 1, fp);
		fprintf(fw, "%02x\n", tt[0]);
	}
	fprintf(fw, "ENDCHAR\n");

	return  1;
}

int vga12x24_out(FILE *fp, FILE *fw, int count, int ofs)
{
	u_char  tt[2];
	int	i;

	fprintf(fw, "STARTCHAR C%03d\n", count);
	fprintf(fw, "ENCODING %d\n", count);
	fprintf(fw, "SWIDTH 508 0\n");
	fprintf(fw, "DWIDTH 12 0\n");
	fprintf(fw, "BBX 12 24 0 -2\n");
	fprintf(fw, "BITMAP\n");

	for(i=0; i<24; i++) {
	     fread(tt, 1, 2, fp);
	     fprintf(fw, "%02x%02x\n", tt[0], tt[1]);
	}
	fprintf(fw, "ENDCHAR\n");

	return  1;
} 


void EnglishFonts(void)
{
	FILE  *fr;
	int    i;

 	fr = OpenFile(FD->fn1, etpath, "rb", NULL);

 	fputs(FD->head, stdout);
 	for(i=0; i<256; i++)
		outfunc(fr, stdout, i, 0);
	fprintf(stdout, "ENDFONT\n");
}


/*---------------------------------------------------------------------

			      Font  Lists

---------------------------------------------------------------------*/

char *IncFont[] = 
	{ "et15", "et24m", "et24k", "et24b", "et24r", "et24s", 
	  "et24l", "vga8x15", "vga12x24", NULL };
FontDef	*FD_Table[] = 
	{ &et15, &et24m, &et24k, &et24b, &et24r, &et24s, &et24l, 
	  &vga8x15, &vga12x24, NULL };
int (*Func_Table[])(FILE *fp, FILE *fw, int count, int ofs) =
	{ et15_out, et24_out, et24_out, et24_out, et24_out, 
	  et24_out, et24_out, vga8x15_out, vga12x24_out, NULL };




int Input(int argc, char *argv[])
{
	DIR   *dp;
	int   i, gargc=1;

	if(argc < 3) {
		fprintf(stderr, 
		        "\net2bdf of xcin ver %s\n\n"
		        "Usage: et2bdf [-d] <ETPATH> <FONTSTL>\n"
		        "  -d        == Debug option (keep the tmpfile).\n"
		        "  <ETPATH>  == Path of Eten system.\n"
		        "  <FONTSTL> == Style of Eten font.\n\n"
		        "Curent supported <FONTSTL>:\n  ",
		        VERSION);
		for(i=0; IncFont[i]!=NULL; i++)
			fprintf(stderr, "%s ", IncFont[i]);
		fprintf(stderr, "\n\n");
		exit(1);
	}

	if(!strcmp("-d", argv[1])) {
		debug = 1;
		gargc ++;
	}
	if((dp=opendir(argv[gargc])) == NULL) {
		fprintf(stderr, "Cannot find the ETPATH  %s.\n", argv[gargc]);
		closedir(dp);
		exit(1);
	}
	closedir(dp);
	strcpy(etpath, argv[gargc++]);

	for(i=0; IncFont[i]!=NULL && strcmp(IncFont[i],argv[gargc]); i++);
	if(IncFont[i] == NULL) {
		fprintf(stderr, "Invalid <FONTSTL>  %s.\n", argv[gargc]);
		exit(1);
	}
	FD = FD_Table[i];
	outfunc = Func_Table[i];

	return  i;
}

FILE *OpenFile(char *fn, char *pw, char *md, char *err_str)
{
	FILE  *fp;
	char   file[256];

	if(pw)
		sprintf(file, "%s/%s", pw, fn);
	else
		strcpy(file, fn);
	if((fp=fopen(file, md)) == NULL) {
		if(err_str)
			fprintf(stderr, "%s\n", err_str);
		else
			fprintf(stderr, "Cannot open the file \"%s\".\n", file);
		exit(1);
	}
	return  fp;
}

int main(int argc, char *argv[])
{
	int  font_label;

	font_label = Input( argc, argv );

	if(font_label>=0 && font_label<7)
		ChineseFonts();
	else if(font_label>=7 && font_label<9)
		EnglishFonts();

	return  0;
}
