/*    parseFMT.C    */
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include "parseafm.h"
int debugit=0;
#define dbg if (debugit)
int chrcat(char *s,char c);
int str_ascii(char *s) ;
int writefmt(void);
/*-----------------------------------------------------------------------*/
/* Globals */
FontInfo *fi;
FLAGS myflags = P_ALL;

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

char fmtname[80];
main( int argc, char **argv)
{
  char *s;
	char filename[80];
	FILE *fp;

	myflags = P_ALL;

	strcpy(filename,*(++argv));
	s = strchr(filename,'.');
	if (s!=NULL) *s=0;
	strcpy(fmtname,filename);
	if (strchr(filename,':')!=NULL) strcpy(fmtname,strchr(filename,':')+1);
	strcat(fmtname,".fmt");
	strcat(filename,".afm");
	printf("Processing {%s}, creating {%s} \n",filename,fmtname);

	if (!filename[0]) {
	  printf ("*** ERROR: can't open. filename is missing.\n",filename );
	  return 0;
	}
	printf("Reading ADOBE font metric file {%s} \n ",filename);
	fp = fopen(filename, "r" );
	if (fp == NULL) {
		printf ("*** ERROR: can't find: %s\n", filename );
		perror("");
		exit(1);
	}

	switch (parseFile(fp, &fi, myflags)) {
	case parseError:
	    printf("*** ERROR: problem in parsing the AFM File.\n");
	    exit(1);
	case ok:
	    fclose(fp);
	    writefmt();
	    break;
	case earlyEOF:
	    printf("The AFM File ended prematurely.\n");
	    exit(1);
	    break;
	default:
	    break;
    }
    printf("Successful completioin \n");
  exit(0);
}

/*-----------------------------------------------------------------------*/
struct xypair {float x,y;} ;
struct allchar {char lig[4],lrep[4],kern[35]; struct xypair kxy[35];
} *ap[256];
/* *ap[256];  */
struct char_data { float wx,wy,x1,y1,x2,y2; } cc ;
struct char_datax { char *kern, *lig, *krep, *lrep; };
struct font_table {
	char *name;
	char *full_name;
	char *file_metric;
	char *file_vector;
	char *file_bitmap;
	struct char_data ( *chr)[256];
	int encoding;           /* 1 = postscript text , 2=postscrip symbol, */
				/* 3=TEX text, 4=TEX symbol, 5=TEX extensions */
	float space,space_stretch,space_shrink;
	float scale,slant,uposition,uthickness;
	float fx1,fy1,fx2,fy2,caphei,xhei,descender,ascender;
} fnt;
FILE *fmt;
int c1,c2,ll,lk,n;

writefmt()
{
	int i = 0,zz;
	double fff;
	char *sss;
	int dec,sgn;
	CharMetricInfo *temp = fi->cmi;
	Ligature *node = temp->ligs;
	PairKernData *pkd = fi->pkd;
	float fval,scl;
	fff = 2;
	/* sss is never used    a.r. */
	/* sss = (char *) ecvt(fff,2,&dec,&sgn); */
#ifdef unix
	fmt = fopen(fmtname,"w");
#else
	fmt = fopen(fmtname,"wb");
#endif
	if (fmt == NULL) {
		perror ("Cant open output file ");
		exit(1);
	}
	fnt.encoding = 1;       /* AdobeStandardEncoding */
	printf("The font name is %s\n", fi->gfi->fontName);
	if (0==strcmp(fi->gfi->encodingScheme,"TEXENCODING")) {
		fnt.encoding = 3;       /* AdobeStandardEncoding */
	}
	if (0==strcmp(fi->gfi->encodingScheme,"AdobeStandardEncoding")) {
		fnt.encoding = 1;       /* AdobeStandardEncoding */
	}
	if (0==strcmp(fi->gfi->encodingScheme,"GLEMARK")) {
		fnt.encoding = 5;
	}
	printf("Encoding scheme {%s} %d \n"
		,fi->gfi->encodingScheme,fnt.encoding);
	fnt.scale = 1000;
	scl = .001;
	fnt.slant = fi->gfi->italicAngle;
	fnt.uposition = fi->gfi->underlinePosition*scl;
	fnt.uthickness =  fi->gfi->underlineThickness*scl;
	fnt.fx1 = fi->gfi->fontBBox.llx*scl;
	fnt.fy1 = fi->gfi->fontBBox.lly*scl;
	fnt.fx2 = fi->gfi->fontBBox.urx*scl;
	fnt.fy2 = fi->gfi->fontBBox.ury*scl;
	fnt.caphei = fi->gfi->capHeight*scl;
	fnt.xhei = fi->gfi->xHeight*scl;
	fnt.descender = fi->gfi->descender*scl;
	fnt.ascender = fi->gfi->ascender*scl;

	temp = fi->cmi;
	zz = 1;
	for (temp=fi->cmi;zz < fi->numOfChars; temp++) {
		zz++;
		if (temp->code==32) {
			fnt.space = temp->wx*scl;
			fnt.space_stretch = fnt.space*.5;
			fnt.space_shrink = fnt.space*.3;
			break;
		}
	}

	temp = fi->cmi;
	fwrite(&fnt.encoding,4,16,fmt);

	zz = 0;
	for (i = 0; i < 256 ; ++i) {
	  if (i<temp->code || zz >= fi->numOfChars ) {
		cc.wx = 0;
		cc.wy = 0;
		cc.x1 = 0;
		cc.x2 = 0;
		cc.y1 = 0;
		cc.y2 = 0;
	  } else {
		cc.wx = temp->wx*scl;
		cc.wy = temp->wy*scl;
		cc.x1 = temp->charBBox.llx*scl;
		cc.x2 = temp->charBBox.urx*scl;
		cc.y1 = temp->charBBox.lly*scl;
		cc.y2 = temp->charBBox.ury*scl;
		  for (node=temp->ligs;node !=NULL; node = node -> next) {
		if (ap[i]==NULL) ap[i] = calloc(1,sizeof(*ap[i]));
		if (ap[i]==NULL) printf("memory allocation error \n");
			chrcat(ap[i]->lig,str_ascii(node->succ));
			chrcat(ap[i]->lrep,str_ascii(node->lig));
		  }
		zz++;
		temp++;
	  }
	  fwrite(&cc,sizeof(cc),1,fmt);
	} /* for */
	dbg printf("got char %d %d\n",i,zz);

	dbg printf("Here comes the pair kerning data ...\n");
	if (fi->numOfPairs != 0) {
	  for (i = 0; i < fi->numOfPairs; ++i) {
		c1 = str_ascii(pkd[i].name1);
		c2 = str_ascii(pkd[i].name2);
		if (ap[c1]==NULL) ap[c1] = calloc(1,sizeof(*ap[c1]));
		if (ap[c1]==NULL) printf("memory allocation error \n");
		chrcat(ap[c1]->kern,c2);
		n = strlen(ap[c1]->kern)-1;
		ap[c1]->kxy[n].x = pkd[i].xamt*scl;
		ap[c1]->kxy[n].y = pkd[i].yamt*scl;
	  }
	}

	for (i=1;i<256;i++) {
		if (ap[i]==NULL) continue;
		ll = strlen(ap[i]->lig);
		lk = strlen(ap[i]->kern);
		if (ll>0 || lk>0) {
			fputc(i,fmt);
			fputc(ll,fmt);
			fwrite(ap[i]->lig,1,ll,fmt);
			fwrite(ap[i]->lrep,1,ll,fmt);
			fputc(lk,fmt);
			fwrite(ap[i]->kern,1,lk,fmt);
			fwrite(ap[i]->kxy,8,lk,fmt);
		}
	}
	fputc(0,fmt);
	fclose(fmt);
}
chrcat(char *s,char c)
{
	int i;
	i = strlen(s);
	*(s+i) = c;
}
int str_ascii(char *s)
{
	int i;
	CharMetricInfo *temp = fi->cmi;

	for (i=0;i<fi->numOfChars; ++i) {
		if (strcmp(temp->name,s)==0) {
			return temp->code;
		}
		temp++;
	}
	printf("Failed to find char, fatal error ********* {%s} \n",s);
}
