/*
*               TeX Device Driver DVIOUT, DVIPRT で
*               書体倶楽部のアウトラインフォントを使う
*
*                             vfont.c
*
*     "本プログラムは、Hideki Yoshida 氏の vfondisp.c を元にして作製
*      されています。また、get_ten で吉澤氏のバッファリングのアイデ
*      アを使用し、更に、向内さんの書かれた dvii という dvi ドライバ
*      のアウトラインフォント展開アルゴリズムを使用して、展開されるフ
*      ォントの質の向上をはかった精細モードを設けました。"
*
*                      1991-92  by T.Minagawa
*
*	26 Jan 1993 : modified to utilize tpic functions for expansion by Oh-Yeah?
*	Note: Here the use of tpic is very tricky and deeply indebted to primitive
*	functions in tpic.c, so that even slight modification in tpic.c would
*	require some reconsideration for the routines.
*
*	1 Sept 1992 : slightly modified for version check by sempa.
*  12 Nov  1992 : modified for JGfont(3D-Bezier) by Naochan!
*  27 Nov  1992 : slightly modified for NTTjTeX by Yakumo
*  14 Nov. 1993 : modified for TT font by I.Matsuda
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>

#ifdef  UNIX
#include <unistd.h>
#else
#include <io.h>
#ifdef	MSVC
#include "msvcdir.h"
#else
#include <dir.h>
#endif
#endif

#define _DEF_STDIO_H_
#include "dd.h"
#include "err.h"
#include "vfont.h"
#include "vraster.h"
#ifdef	CC_JPN
#include <jctype.h>
#else
#ifdef TTFONT
#include "ttfont.h"
#endif
#include "inter.h"
#ifdef	USE_SUBFONT
#include "subfont.h"
#endif

unsigned short jistojms(unsigned short);
# ifdef BEZIERFONT
static int jisl1(unsigned short);
# endif
static int jisl2(unsigned short);

#endif

/* winjtt.c */
int AccessTT(char *);

#ifdef	USE_COLOR
/* epsbox.c */
void set_black(int);
#endif

static int jislgaiji(unsigned short);

/* グローバル変数 */
V_JFM *vjfm_top;	/* vjfm リストの先頭を示すポインタ */
struct _v_font dummy =
{
	"?",
	V_ERROR,
	{-1, -1, -1},
	0, 0, 0,
	UNKNOWN
};

#ifdef VFD
V_JFM *vfd_top;

#endif

V_FONT *vfont[MAX_VFONT] =
{&dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,

 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,

 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,

 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy,
 &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy};
const int s_ratio[3] =
{180, 372, 591};

/*
		tan(10) * ( MAX_VLUE + 1 )
		tan(20) * ( MAX_VLUE + 1 )
		tan(30) * ( MAX_VLUE + 1 )
	*/

#ifdef VFTPIC
/* bitmap.c */
void init_alter_bitmap(BUFFER *dest, PIXEL d_linewidth_byte);
void fin_alter_bitmap(void);

/* tpic.c */
extern int f_tpic_turn_on;

#define TPIC_MI long	/* type of tpic milli-inches (x, y) */
typedef struct {
	PIXEL x, y;
} pixelpoint;

void set_grayscale(double gray);
void rasterize_line(pixelpoint start, pixelpoint end, BOOL mask_head,
					BOOL mask_tail);
void set_visible(PIXEL visible, PIXEL invisible);
void raster_draw(void);	/* draw pixels defined in stack */
void set_pensize(TPIC_MI pensize);
void raster_fill(void);
void clean_bucket(void);
void freeze_tpic_status(void);
void melt_tpic_status(void);

#endif

/* init.c prtinit.c */
extern int tategaki;
extern char ptex_mode;

/* main.c */
extern int f_osversion;

/* buffer.c */
char *dup_string(char *);
void *marea(unsigned int);

/* fontdef.c */
KFONT *dup_kf(KFONT *);

/* loadpk.c */
int openf(char *, int);
extern int f_flush_pk;

/* option.c */
int make_path(char *path, char *dir, char *name, char *ext);

/* vraster.c */
int draw_fine(VPARA_TBL *);

/* vdata.c */
int get_yofs(VPARA_TBL *);
int readdata(VPARA_TBL *, DRAW_MODE);
extern int linecount;
extern int itemcount;
extern Line *linebuf;
extern Line *linebuf_end;

int get_term(char *, char *, int, int);
static int far *get_novec(char *);
void bbox(BUFFER *, int);
static void bigbox(BUFFER *, long, int);
V_JFM *get_vjfm(int vjfm_no);
static int open_vfont(int, char *, char *, char *, char *);

#ifdef VFTPIC
static int draw_character(VPARA_TBL *);
static pixelpoint vf_to_abs(VPARA_TBL *, int x, int y);
/* convert font coord to bitmap coord */

#else
static int draw_character(VPARA_TBL *);
static void trace_outline(VPARA_TBL *, int, int, int, int);
static void fill_edges(VPARA_TBL *, int, int, int, int);

#endif

#ifdef TTFONT
/* ttfont.c */
int get_ttinfo(int, int);
#ifdef	USE_ETF
unsigned char *GetHoffset(FONT_INFO *);
char *check_etfmap(char *);
extern BOOL	f_make_wjtetf;
#endif
/* sptopxl.asm  */
PIXEL sptopixel(SCALED_PT);
int f_use_ttf = 1;
#endif

void free_vdata(void);
void free_vraster(void);

void flush_vfont(void)
{
	int i;
	V_JFM *vjfm_tmp, *vjfm_next;

	for (vjfm_tmp = vjfm_top; vjfm_tmp != NULL; ){
		 vjfm_next = vjfm_tmp->next;
		 Free(vjfm_tmp);
		 vjfm_tmp = vjfm_next;
	}
	vjfm_top = NULL;
	for(i = 0; i < MAX_VFONT; i++){
		if(vfont[i] != &dummy){
			Free(vfont[i]);
			vfont[i] = &dummy;
		}
	}
}

#ifdef	USE_WINFONT
extern V_JFM *v_tfm;
static char *ftt_buf;
static char **ftt_pt;
static int ftt_count;

#define	CHAR_SET	0x10000

struct FONT_ATTR {
	char *key;
	int type;
} font_attr[] = {
	"ansi", 		0	| CHAR_SET,
	"arabic",		178 | CHAR_SET,
	"baltic",		186	| CHAR_SET,
	"bold",			'B',
	"chinesebig5",	136 | CHAR_SET,
	"cid2uni",		'c',
	"default",		1	| CHAR_SET,
	"easteurope",	238 | CHAR_SET,
	"gb2312",		134 | CHAR_SET,
	"greek",		161 | CHAR_SET,
	"hangeul",		129 | CHAR_SET,
	"hebrew",		177 | CHAR_SET,
	"italic",		'I',
	"jis2uni",		'j',
	"johab",		130 | CHAR_SET,
	"mac",			77	| CHAR_SET,
	"oem",			255 | CHAR_SET,
	"regular",		'R',
	"russian",		204 | CHAR_SET,
	"shiftjis",		128	| CHAR_SET,
	"strikeout",	'O',
	"symbol",		2	| CHAR_SET,
	"turkish",		162 | CHAR_SET,
	"thai",			222 | CHAR_SET,
	"underline",	'U',
	"unicode",		'C',
	"vietnamese",	163 | CHAR_SET,
	"\x7f",			0x7f,
};

int compare(char **arg1, char **arg2)
{
	return strcmp(*arg1, *arg2);
}

/***********************************************
*		Read Font Map file(ttfonts.map)
************************************************/
void DefineFTT(char *fname)
{
	#define	MAXFNUM	0x40
	uchar lbuf[0x200];
	uchar subbuf[0x20];
	uchar attrib_buf[0x20];
	uchar *ffname[MAXFNUM];
	FILE *fp;
	uchar *s, *t, *u, *t_buf, *s0;
	int fdel, size, code, i, left, right, f_skip, pos, fnum, f_uni;

	if(fname == NULL || *fname == 0){
		Free0(ftt_pt);
		ftt_pt = NULL;
		ftt_count = 0;
		return;
	}
	DefineFTT(NULL);
	subbuf[0] = '/';
	size = fnum = 0;
	pos = -1;

	fp = fopenf(fname, "rt");
	if(fp == NULL)
		return;
rep:
	s = (uchar *)marea(filelength(fileno(fp)) + size);
	if(size){
		memcpy(s, t_buf, size);
		Free0(t_buf);
	}
	t_buf = s;
	s += size;
	f_skip = f_uni = 0;
	while(fgets(lbuf, 0x200, fp) != NULL){
		t = lbuf;
		while(*t == ' ' || *t == '\t')
			t++;
		if(f_skip){
			if(!strcmp(t, "%endskip\n"))
				f_skip = 0;
			continue;
		}
		if(*t == '%'){
			if(!strcmp(t+1, "skip\n")){
				f_skip = 1;
				continue;
			}
			if(strncmp(t+1, "input", 5))
				continue;
			t += 6;
			if(*t > ' ')
				continue;
			while(*t == ' ' || *t == '\t')
				t++;
			if(fnum >= MAXFNUM-1){
				error(WARNING, "Too many included files for -ftt:");
				continue;
			}
			if(*t == '\"'){
				fdel = 1;
				if(!*++t)
					continue;
			}else
				fdel = 0;
			size = strlen(t);
			u = ffname[fnum++] = (char *)marea(size + strlen(fname) + 1);
			strcpy(u, fname);
			if(pos < 0){
				pos = strlen(fname) - 1;
				while(pos > 0 && u[pos] != '\\' && u[pos] != ':')
					pos--;
				pos++;
			}
			for(size = pos; *t && *t != '\n'; ){
				if(fdel){
					if(*t == '\"')
					break;
				}else if(*t <= ' ')
					break;
				if(issjis1(*t) && t[1])
					u[size++] = *t++;
				u[size++] = *t++;
			}
			u[size] = 0;
			continue;
		}
		if(!*t || *t == '\n' || *t == ';' || *t == '#')
			continue;
		if(*t == 0x22){
			fdel = 1;
			if(!*++t)
				continue;
		}else
			fdel = 0;
		ftt_count++;
		s0 = s;
		while(1){
			*s++ = *t++;
			if( !fdel ) 	/* not starting by '"' */
				if( *t <= ' ' ) break; /* less than ' ', including TAB. */
			else if( *t == '\"' )
			{ /* starting from '"' and current == '"', stop here. */
				t++; /* To ignore '"', step t one more. */
				break;
			}
			else if( !*t ) /* starting from '"' and current == NULL. */
				break;
		}
		*s++ = 0;
		if(!*t){
ct:			*s++ = '#'; /* means wrong. */
			*s++ = 0;
			continue;
		}
		/* skip blank chars. */
		while(*t == ' ' || *t == '\t') t++;
		if(!*t || *t == '\n' || *t == ';' || *t == '#' || *t == '%')
			goto ct;
		/* 2nd step. copying Windows-Font name. */
		if(*t == '\"'){
			fdel = 1;
			if(!*++t)
				goto ct;
		}else
			fdel = 0;
		while(1){
#ifndef	UNIX
			code = *s++ = *t++;
#ifdef	USE_SUBFONT
			if (IsJapanese()){
				if(issjis1(code) && *t)
					*s++ = *t++;
			}else if(code >= 0x81 && code <= 0xfe && *t)
#else
			if(issjis1(code) && *t)
#endif
#endif
			*s++ = *t++;
			if(!fdel){
				if(*t <= ' ')
					break;
			}
			else if(!*t)
				goto next;
			else if(*t == '\"'){
				t++;
				break;
			}
		}
		while(*t <= ' '){
			if(!*t++)
				goto next;
		}
		/* skip blank chars. */
		while( *t == ' ' || *t == '\t' ) t++;
		if(!*t || *t == '\n' || *t == ';' || *t == '#' || *t == '%')
			goto next;
		/* 3rd step. setting attributes of the font. */
		size = 1;
		code = -1;
		u = attrib_buf;
		while( u < attrib_buf + 32)
		{
			*u++ = tolower(*t);
			if(!*++t || *t == '\n' || *t == ';' 
				|| *t == '#' || *t == '%' || *t == ':' || *t == ','
				|| *t == '\t' || *t == ' ')
			{
				*u = 0;
				left = 0;
				right = sizeof(font_attr)/sizeof(struct FONT_ATTR) -1;
				while(left <= right){
					i = (left+right)/2;
					if( (fdel = strcmp(attrib_buf, font_attr[i].key) ) < 0 ){
						right = i - 1;
						continue;
					}else if(fdel > 0){
						left = i + 1;
						continue;
					}
					fdel = font_attr[i].type;
					if(fdel & CHAR_SET)
						code = fdel & 0xffff;
					else{
						if( (fdel == 'C' || fdel == 'j' || fdel == 'c') 
								/* unicode is supported only by Windows2000 or later */
						  && (f_osversion < 0 || (f_osversion & 0xff) < 5) )
							f_uni = 1;
						if(fdel == 'j'){
							strcpy(subbuf+size, "C[932]");
							size += 6;
						}else if(fdel == 'c'){
							sprintf(subbuf+size, "C[-2]");
							size += 5;
						}else
							subbuf[size++] = fdel;
					}
					break;
				}
				u = attrib_buf;
				if( *t == ':' || *t == ',' )
				{
					t++;
					while( *t == ' ' || *t == '\t' ) t++;
					if(!*t || *t == '\n' || *t == ';' 
						|| *t == '#' || *t == '%' )
						break;
					else
						continue;
				}
				else
					break;
			}		/* completed to interpretate an attribute */
			else
				continue;
		}
		if(f_uni){	/* unicode is supported by Windows2000 or later */
			f_uni = 0;
			s = s0;
			ftt_count--;
			continue;
		}
		if(code >= 0){
			sprintf(subbuf+size, "(%d)", code);
			size = strlen(subbuf);
		}
		if(size > 1){
			for(i = 0; i < size; )
				*s++ = subbuf[i++];
		}
next:	*s++ = 0;
	}
	fclose(fp);
	for(size = 0; size < fnum; size++){
		if(ffname[size]){
			fp = fopenf(ffname[size], "rt");
			if(fp == NULL){
				if(ffname[size][pos] != '$')
					error(WARNING, "Cannot open included font map file %s", 
						ffname[size]);
				else if(!strcmp(ffname[size]+pos, "$user.map")){
					fp = fopenf(ffname[size], "wt");
					fputs("; In this file one may define the font mappings or the files to be input.\n"
						  "; This file will not be overwritten by dviout (verion up).\n;\n", fp);
					fclose(fp);
					fp = NULL;
				}
			}
			Free0(ffname[size]);
			ffname[size] = NULL;
			if(fp == NULL)
				continue;
			size = s - t_buf;
			goto rep;
		}
	}
	*s++ = 0;
	if(ftt_count){
		size = s - t_buf;
		ftt_pt = (char **)marea(size + sizeof(char *)*ftt_count+1);
		ftt_buf = (char *)(ftt_pt + ftt_count);
		*ftt_buf++ = 0;				// make a boundary
		memcpy(s = ftt_buf, t_buf, size);
		for(fdel = 0; s - ftt_buf < size && fdel < ftt_count; ){
			ftt_pt[fdel++] = s;
			while(*s++);
			while(*s++);
		}
	}
	Free0(t_buf);
#if	0
	for(size = 0; size < ftt_count; size++){
		fdel = size;
		while(fdel-- > 0 && strcmp(ftt_pt[fdel], ftt_pt[fdel+1]) > 0){
			s = ftt_pt[fdel];
			ftt_pt[fdel] = ftt_pt[fdel+1];
			ftt_pt[fdel+1] = s;
		}
	}
#else
	qsort(ftt_pt, ftt_count, sizeof(char *), (COMP)compare);
#endif
/*
	for(size=0; size < ftt_count; size++)
		error(C_MSG, "%s %s\n", ftt_pt[size], 
			ftt_pt[size] + strlen(ftt_pt[size]) + 1);
*/
}

void fttInfo(void)
{
	int pt;

	if(ftt_count){
		for(pt=0; pt < ftt_count; pt++)
			error(C_MSG, "%-10s \"%s\"\n", ftt_pt[pt], 
			  ftt_pt[pt] + strlen(ftt_pt[pt]) + 1);
		error(DATATITLE, "Font Mapping:#%d", ftt_count);
	}else
		error(WARNING, "NO font mapping");
}

char *check_ftt(char *tfm)
{
	int top, end, pt, res;
	char *s;

#ifdef	USE_SUBFONT
	current_sfd_id = -1;
#endif
#ifdef	USE_ETF
	if((s = check_etfmap(tfm)) != NULL)
		return s;
#endif
	for(top = 0, end = ftt_count-1; top <= end; ){
		pt = (top + end)/2;
#ifdef	USE_SUBFONT
		if (s = strchr(ftt_pt[pt], '@')) {
			int len = s - ftt_pt[pt];
			if (len < strlen(tfm) &&
				!strncmp(ftt_pt[pt], tfm, len) &&
				load_sfd_record(s+1, tfm+len) >= 0) {
				s = ftt_pt[pt];
				while(*s++);
				return s;
			}
		}
#endif
		res = strcmp(tfm, ftt_pt[pt]);
		if(res > 0)
			top = pt + 1;
		else if(res < 0)
			end = pt - 1;
		else{
			s = ftt_pt[pt];
			while(*s++);
				return s;
		}
	}
	return tfm;
}

void chg_ftt(char *tfm, char *name)
{
	char *s, *t;
	int pt, top, end, res;

	for(top = 0, end = ftt_count-1; top <= end; ){
		pt = (top + end)/2;
		res = strcmp(tfm, ftt_pt[pt]);
		if(!res)
			break;
		if(res > 0)
			top = pt + 1;
		else if(res < 0)
			end = pt - 1;
	}
	if(top > end)
		pt = -1;
	for(s = common_work, top = 0; top < ftt_count && 
	  s < common_work + (COMMON_SIZE - 0x100); top++){
		if(top == pt)
			continue;
		t = ftt_pt[top];
		while(*s++ = *t++);
		while(*s++ = *t++);
	}
	if(s - common_work + sizeof(char *)*ftt_count > COMMON_SIZE - 0x100){
		error(WARNING, "Too many definitons of font map");
		return;
	}
	if(pt >= 0)
		ftt_count--;
	if(name != NULL){
		ftt_count++;
		t = tfm;
		while(*s++ = *t++);
		t = name;
		while(*s++ = *t++);
	}
	end = s - common_work;
	Free0(ftt_pt);
	ftt_pt = (char **)marea(end + sizeof(char *)*ftt_count);
	memcpy(s = t = (char *)(ftt_pt + ftt_count), common_work, end);
	for(pt = 0; s - t < end && pt < ftt_count; ){
		ftt_pt[pt++] = s;
		while(*s++);
		while(*s++);
	}
	qsort(ftt_pt, ftt_count, sizeof(char *), (COMP)compare);
}


char *check_myftt(char *name, int mode)
{
	char *s, *t;
	static char fname[MAX_PATH];

	fname[0] = 0;
	s = check_ftt(name);
	if( s == name || !(t = strstr(s, ".ttf")) )
		return fname;
	if(!t[4])
		return mode?fname:s;
	else if(t[4] == '/'){
		if(!mode){
			t[4] = 0;
			strncpy(fname, s, MAX_PATH-1);
			t[4] = '/';
			return fname;
		}else if(mode == 1)
			fname[0] = atoi(t+5);
		else{
			t += 5;
			while(*t >= '0' && *t <= '9')
				t++;
			return t;
		}
	}
	return fname;
}

/*
 *  1. transform  *tfm  if it is defined in  ttfonts.map
 *  2. if  *tfm  is defined in [WinJFont], RETURN its pointer (V_JFM*)
 *  3. RETURN the pointer of "edefault" if   *tfm  is define in Windows system
 *     and "edefault" is defined in [WinJFont]
 *  4. otherwise RETURN  0
 */
V_JFM *check_wintt(char *tfm)
{
	V_JFM *vjfm_tmp;
	static int e_def = 0;

	if(tfm == NULL){
		e_def = 0;
		v_tfm = NULL;
		return NULL;
	}
	tfm = check_ftt(tfm);
	for (vjfm_tmp = vjfm_top; vjfm_tmp != NULL; ){
		if(!stricmp(vjfm_tmp->name, tfm))
			return vjfm_tmp;
		vjfm_tmp = vjfm_tmp->next;
	}
	if(!e_def){
		e_def = 1;
		for (vjfm_tmp = vjfm_top; vjfm_tmp != NULL; ){
			if(!stricmp(vjfm_tmp->name, "edefault")){
				v_tfm = vjfm_tmp;
				break;
			}
			vjfm_tmp = vjfm_tmp->next;
		}
	}
	return AccessTT(tfm)?NULL:v_tfm;
}
#endif


/*************************************************************
*	get_vfont_name
*	vector font config file から情報を取得する
**************************************************************/
int get_vfont_name(char *cfg_name)
{
	FILE *fp;
	char buf1[BUFSIZE], buf2[BUFSIZE], buf3[BUFSIZE], jfm_name[NAMELEN];
	char version[VER_LEN + 1] = "?";
	V_JFM *vjfm;
	V_JFM *before = NULL;

#ifdef VFD
	V_JFM *vfd_before = NULL;
	int vfd_count = 0;

#endif
	int long_wide, slant, sw, threshold, thin, _xfat, _yfat, rotation;
	int i, l = 0, job = 0, counter = 0;
	int f_goth, width_adj, height_adj;
	int far *novec;
	int	pos;
	char *pt;

#ifdef	USE_WINFONT
	int m11, m12, m21, m22;
#endif

	if(*cfg_name == '\n'){
		fp = NULL;
		pt = cfg_name + 1;
	}else if ((fp = fopenf(cfg_name, "rt")) == NULL){
		error(C_MSG, "File:%s\n", cfg_name);
		return (-1);
	}

	while(1){
		l++;
		if(fp){
			if(fgets(buf1, BUFSIZE - 1, fp) == NULL)
				break;
		}else{
			while(*pt == 0x0d || *pt == 0x0a)
				pt++;
			if(*pt == 0)
				break;
			for(pos = 0; (buf1[pos] = pt[pos]) != 0 && pos < BUFSIZE - 1;
			  pos++){
				if(buf1[pos] == 0x0d || buf1[pos] == 0x0a){
					buf1[pos++] = 0;
					break;
				}
			}
			pt += pos;
		}
		if (buf1[0] == '#')
			continue;			/* '#' はコメント行 */

		/* キーワードのチェック */
		if (buf1[0] == '%') {
			if (strlcmp(&buf1[1], "version") == 0) {
				if (get_term(buf2, buf1, 2, '=') == 0)
					continue;
				strncpy(version, buf2, VER_LEN);
				continue;
			}
			else if (strlcmp(&buf1[1], "vfont_list") == 0) {
				job = 1;
				continue;
			}
			else if (strlcmp(&buf1[1], "jfm_list") == 0) {
				job = 2;
				continue;
			}
			else {
				return (l);
			}
		}

		if (job == 0) {
			/* エラー */
			return (l);
		}
		else if (job == 1) {
			/* ベクトルフォントの情報を取得 */
			if (get_term(buf2, buf1, 1, DELIM1) == 0)
				continue;
			i = atoi(buf2) - 1;
			if (i < 0 || MAX_VFONT - 1 < i) {
				return (l);
			}
			if (get_term(buf2, buf1, 2, DELIM1) == 0)
				continue;
			vfont[i] = (V_FONT *) marea(sizeof(V_FONT) + strlen(buf2) + 1);
			strcpy( (char *)vfont[i]->v_font_name = 
					((char *)(vfont[i])) + sizeof(V_FONT), buf2);
			vfont[i]->status = V_CLOSE;
			vfont[i]->v_fh[0] = vfont[i]->v_fh[1] = 
				vfont[i]->v_fh[2] = 0;

			/* 幅のアジャスト Tomiie */
			if (get_term(buf2, buf1, 3, DELIM1) == 0 ||
				(width_adj = atoi(buf2)) < 200 || 2000 < width_adj) {
				width_adj = 1000;
			}
			vfont[i]->width_adj = width_adj;

			/* 高さのアジャスト Tomiie */
			if (get_term(buf2, buf1, 4, DELIM1) == 0 ||
				(height_adj = atoi(buf2)) < 200 || 2000 < height_adj) {
				height_adj = 1000;
			}
			vfont[i]->height_adj = height_adj;

			if (get_term(buf2, buf1, 5, DELIM1) != 0 &&
				atoi(buf2) > 0 && vfont[i]->v_fh[1] == 0)
				vfont[i]->v_fh[1] = -1;

			vfont[i]->yoffset = MAX_VALUE + 1;
		}
		else {
			/* 各 JFM に対応するベクトルフォントの番号、
				フォントの変形、およびフォント描画方法を取得 */
			if (get_term(buf2, buf1, 1, DELIM1) == 0)
				continue;
			strcpy(jfm_name, buf2);
			if (get_term(buf2, buf1, 2, DELIM1) == 0)
				continue;
			i = atoi(buf2) - 1;
#ifndef VFD
			if (i < 0 || MAX_VFONT - 1 < i) {
#else
			if (i < -1 || MAX_VFONT - 1 < i) {
#endif
				return (l);
			}

			/* 長／平体のチェック */
			if (get_term(buf2, buf1, 3, DELIM1) == 0 ||
				buf2[0] < 'a' || buf2[0] == 'f' || 'j' < buf2[0])
				buf2[0] = 'a';
			long_wide = (int)buf2[0];

			/* 斜体のチェック */
			if (get_term(buf2, buf1, 4, DELIM1) == 0 ||
				buf2[0] < 'a' || 'm' < buf2[0])
				buf2[0] = 'a';
			slant = (int)buf2[0];

			/* フォント描画方法のチェック */
			if (get_term(buf2, buf1, 5, DELIM1) == 0 ||
				(buf2[0] != 'n' && buf2[0] != 'o'
				 && buf2[0] != 'f')) {
				buf2[0] = 'n';
			}
			sw = (int)buf2[0];
			if (sw == (int)'n' || sw == (int)'f')
				threshold = atoi(&buf2[1]);

			/* フォント線幅調整パラメータの読み取り */
			get_term(buf2, buf1, 6, DELIM1);
#if 0
			if (get_term(buf3, buf2, 1, DELIM2) == 0 ||
				(thin = atoi(buf3)) < -100 || 100 < thin) {
				thin = DEF_THIN;
			}
#else
			if (get_term(buf3, buf2, 1, DELIM2) != 0)
				thin = atoi(buf3);
			else
				thin = 0;
#endif
			_xfat = _yfat = 0;
			if (get_term(buf3, buf2, 2, DELIM2) != 0)
				_xfat = atoi(buf3);
			if (get_term(buf3, buf2, 3, DELIM2) != 0)
				_yfat = atoi(buf3);

			/* vec font 不使用のサイズの読み取り */
			if (get_term(buf2, buf1, 7, DELIM1) == 0)
				novec = NULL;
			else
				novec = get_novec(buf2);

			/* 疑似ゴシックの変更 Tomiie */
			if (get_term(buf2, buf1, 8, DELIM1) == 0 ||
				(f_goth = atoi(buf2)) < 1 || 2 < f_goth) {
				f_goth = 0;
			}

			/* rotation の読み取り */
			if (get_term(buf2, buf1, 9, DELIM1) == 0)
				rotation = 0;
			else
				rotation = atoi(buf2) % 4;

			vjfm = (V_JFM *)marea(sizeof(V_JFM));

#ifndef VFD
			if (counter++ == 0)
				vjfm_top = vjfm;
			else
				before->next = vjfm;

			before = vjfm;
#else
			if (i == -1) {
				if (vfd_count++ == 0)
					vfd_top = vjfm;
				else
					vfd_before->next = vjfm;
				vfd_before = vjfm;
			}
			else {
				if (counter++ == 0)
					vjfm_top = vjfm;
				else
					before->next = vjfm;
				before = vjfm;
			}
#endif
			strcpy((char *)vjfm->name, jfm_name);
			vjfm->font_no = i;
			vjfm->long_wide = long_wide;
			vjfm->slant = slant;
			vjfm->draw_sw = sw;
			vjfm->threshold = threshold;
			vjfm->thin = thin;
			vjfm->_xfat = _xfat;
			vjfm->_yfat = _yfat;
			vjfm->novec = novec;
			vjfm->rotation = rotation;
			vjfm->f_goth = f_goth;
			vjfm->next = NULL;
		}
	}
	if(fp)
		fclose(fp);
	get_term(buf2, VFN_VERSION, 1, '*');
	if (atoi(buf2) != atoi(version)) {
		/* vfnのバージョンは整数部のみでチェック */
		error(WARNING, "[vfont] vfn file version mismatch."
				" x(%s) -> o(%s)", version, buf2);
	}
	/* vjfmとvfont[]が対応しているかチェック */
	for (vjfm = vjfm_top; vjfm != NULL; vjfm = vjfm->next) {
		if (vfont[vjfm->font_no] == &dummy) 
			error(WARNING, "[vfont] vfn file error. "
					"JFM(%s) <-> Vector font No.%d.",
					(char *)vjfm->name, vjfm->font_no);
		else if(vfont[vjfm->font_no]->v_font_name[0] != ' '){
			if(vjfm->_xfat < 0 || vjfm->_xfat > 100)
				vjfm->_xfat = 0;
			if(vjfm->_yfat < 0 || vjfm->_yfat > 100)
				vjfm->_yfat = 0;
			if(vjfm->thin < -100 || vjfm->thin > 100)
				vjfm->thin = DEF_THIN;
		}
#ifdef	USE_WINFONT
		else{
			if(vjfm->_xfat < -2000 || vjfm->_xfat > 2000)
				vjfm->_xfat = 0;
			if(vjfm->_yfat < -2000 || vjfm->_yfat > 2000)
				vjfm->_yfat = 0;
			if(vjfm->thin < 0 || vjfm->thin > MAX_THIN)
				vjfm->thin = 0;
			m12 = m21 = 0;
			m11 = 65536*vfont[vjfm->font_no]->width_adj/1000;
			m22 = 65536*vfont[vjfm->font_no]->height_adj/1000;
			if ((int)'b' <= vjfm->long_wide
				&& vjfm->long_wide <= (int)'e') {
				if(vjfm->rotation & 1)
					m22 = m22 * (10 - (vjfm->long_wide - (int)'a')) / 10;
				else
					m22 = m22 * 10/(10 - (vjfm->long_wide - (int)'a'));
			}
			else if ((int)'g' <= vjfm->long_wide
			  && vjfm->long_wide <= (int)'j') {
				if(vjfm->rotation & 1)
					m22 = m22 * 10/(10 - (vjfm->long_wide - (int)'f'));
				else
					m22 = m22 * (10 - (vjfm->long_wide - (int)'f')) / 10;
			}
			if (vjfm->slant != (int)'a') {
			i = (vjfm->slant - (int)'b') % 3;
			if ((int)'b' <= vjfm->slant && vjfm->slant <= (int)'g') {
				m21 = 6554*m11/m22*10*s_ratio[i]/(MAX_VALUE + 1);
				if(vjfm->slant >= (int)'e')
					m21 = -m21;
			}
			else {
				m12 = 6554*m22/m11*10*s_ratio[i] / (MAX_VALUE + 1);
				if(vjfm->slant >= (int)'k')
					m12 = -m12;
			}
		}
#if	0
		switch(vjfm->rotation){
			case 1:
				vjfm->mat.eM11 = -m21;
				vjfm->mat.eM12 = -m11;
				vjfm->mat.eM21 = m22;
				vjfm->mat.eM22 = m12;
				break;
			case 2:
				vjfm->mat.eM11 = -m11;
				vjfm->mat.eM12 = -m12;
				vjfm->mat.eM21 = -m21;
				vjfm->mat.eM22 = -m22;
				break;
			case 3:
				vjfm->mat.eM11 = m21;
				vjfm->mat.eM12 = m11;
				vjfm->mat.eM21 = -m22;
				vjfm->mat.eM22 = -m12;
				break;
			default:
				vjfm->mat.eM11 = m11;
				vjfm->mat.eM12 = m12;
				vjfm->mat.eM21 = m21;
				vjfm->mat.eM22 = m22;
				break;
		}
#else
		vjfm->mat.eM11 = m11;
		vjfm->mat.eM12 = m12;
		vjfm->mat.eM21 = m21;
		vjfm->mat.eM22 = m22;
#endif
	  }
#endif
	}
	return (0);
}

/*************************************************************
*	get_term
*	*src から num番目の項目を取得して *dest に入れる
**************************************************************/
int get_term(char *dest, char *src, int num, int delimiter)
{
	int count = 0, i;
	int quote = 0;

	num--;
	for (i = 0; i < num; i++) {
		src = strchr(src, delimiter);
		if (src == NULL)
			return (0);
		src++;
	}

	while (*src != '\0') {
		if (*src == 0x22){
			if (quote++)
				break;
			*dest++ = ' ';
			src++;
		}
		else if (*src == '\n' || *src == delimiter) {
			break;
		}
		else if (!quote && ((*src == '\t') || (*src == ' '))) {
			src++;
		}
		else {
			*dest++ = *src++;
			count++;
		}
	}
	*dest = '\0';
	return (count);
}

/*************************************************************
*	get_novec
*	ベクトルフォントを使わないサイズを取得する
**************************************************************/
int far *
	get_novec(char *src)
{
	int far *table;
	int i, num;
	char *tmp, buf[4];

	tmp = src;
	for (num = 1, i = 0; *tmp != '\0'; tmp++, i++) {
		if (*tmp == DELIM2) {
			num++;
			i = 0;
		}
		else if (i > 2) {
			error(WARNING, "[vfont] Novec size is too large.");
			return (NULL);
		}
	}
	table = (int far *)marea(sizeof(int) * num + 1);

	table[0] = num;
	for (i = 1; i <= num; i++) {
		get_term(buf, src, i, DELIM2);
		table[i] = atoi(buf);
	}
	return (table);
}

/*************************************************************
*	get_vjfm
*	vjfm のリストの vjfm_no番目の vjfmへのポインタを返す
**************************************************************/
V_JFM *
	get_vjfm(int vjfm_no)
{
	int i;
	V_JFM *vjfm_tmp;

	for (vjfm_tmp = vjfm_top, i = 0; i < vjfm_no;
		 vjfm_tmp = vjfm_tmp->next, i++);
	return (vjfm_tmp);
}

BOOL check_vjfm(char *name)
{
	V_JFM *vjfm;

	for (vjfm = vjfm_top; vjfm != NULL; vjfm = vjfm->next) 
		if(!strcmp((char *)vjfm->name, name))
			return TRUE;
	return FALSE; 
}

/*************************************************************
*	get_vfont_list
*	fontcをベクトルフォントで展開するかどうか判定し、
*	その結果およびその他の情報を設定する
**************************************************************/
KFONT *
	get_vfont_list(FONT_INFO *fontc, char *name)
{
	int i, j, font_no, width, height, size, f_tate, fh, adj;
	int far *table, far *wdthp, far *hghtp;
	int find_flg = 0;
	char *org_name;
	FONT_INFO *font;
	FONT_INFO *fontk;
	V_JFM *vjfm;
	V_JFM *vjfm_tmp;
	KFONT *kf;
#ifdef	USE_WINFONT
	char *name2;
#endif

	wdthp = &(fontc->k_width);
	hghtp = &(fontc->k_height);
	if (fontc->f_goth & F_TATE){
		wdthp = hghtp;
		hghtp = &(fontc->k_width);
	}

#ifdef	USE_WINFONT
	name2 = check_ftt(fontc->n);
	if(*name2 == '-' && name2[1] == 0)
		return NULL;
#endif
	width = fontc->k_width;
	height = fontc->k_height;
	f_tate = fontc->f_goth & F_TATE;

	if( (vjfm = check_wintt(fontc->n)) != NULL)
		name = (char *)vjfm->name;
//
//		if(!strcmpi((char *)vjfm->name, "edefault")){
//			name = "edefault";
//		}
//	}

subst:
	for (vjfm = vjfm_top, i = 0; vjfm != NULL;
		 vjfm = vjfm->next, i++) {
		font_no = vjfm->font_no;
		if( (strcmpi((char *)vjfm->name, name)) == 0
#ifdef	USE_WINFONT
		  || (strcmpi((char *)vjfm->name, name2)) == 0
#endif
		 ) {
find:		strcpy(tmp_buf, (char *)vfont[font_no]->v_font_name);
			for (font = first_font_info; font != NULL;
				 font = font->next_font) {
				if ((font->font_type == ZS_FONT
#ifdef BEZIERFONT
					 || font->font_type == JG_FONT
#endif
#ifdef TTFONT
					 || font->font_type == TT_FONT
#endif
					)
					&& ((font->f_goth & F_TATE) == f_tate)
					&& (font->k_width == width)
					&& (font->k_height == height)
					&& (!strcmp((font->ext.kdir)->name, tmp_buf))) {
					vjfm_tmp = get_vjfm((font->ext.kdir)->fh);
/* */
					if (vjfm->long_wide == vjfm_tmp->long_wide
						&& vjfm->slant == vjfm_tmp->slant
						&& vjfm->draw_sw == vjfm_tmp->draw_sw
						&& vjfm->threshold == vjfm_tmp->threshold
						&& vjfm->thin == vjfm_tmp->thin
						&& vjfm->_xfat == vjfm_tmp->_xfat
						&& vjfm->_yfat == vjfm_tmp->_yfat
						&& vjfm->rotation == vjfm_tmp->rotation
						&& vjfm->f_goth == vjfm_tmp->f_goth && 0) {
						if (fontc->k_top == NULL) {
							for (fontk = font; fontk->k_next;
								 fontk = fontk->k_next);
							fontk->k_next = fontc;
							fontc->k_top = fontk->k_top;
						}
						fontc->font_type = font->font_type;
						return (dup_kf(font->ext.kdir));
					}
/* */
				}
			}

			/* ベクトルフォントを使わないサイズに該当していれば
			   NULLを返す */
			if ((table = vjfm->novec) != NULL) {
				for (j = 1; j <= table[0]; j++) {
					if (*wdthp == table[j])
						return (NULL);
				}
			}
			if (vfont[font_no]->status == V_ERROR) {
				return (NULL);
			}
			else if (vfont[font_no]->status == V_OPEN ||
					 vfont[font_no]->status == V_FLUSH) {
				fh = i;
				fontc->font_type = vfont[font_no]->font_type;
				find_flg++;
				break;
			}
			else {
#ifdef	USE_WINFONT
				if(tmp_buf[0] == ' '){
					vfont[font_no]->font_type = fontc->font_type = WINJTT_FONT;
					fh = i;
					find_flg++;
#ifdef	USE_ETF
					if(f_make_wjtetf)
						SetETFindex(fontc, 0, 0, 0, 0, 6);
#endif
					goto def_knj;
				}
#endif
				/* Z's font のオープン */
				if (open_vfont(font_no, (char *)tmp_buf, ".vf1", ".vf2", NULL)
					== TRUE) {
					vfont[font_no]->font_type = fontc->font_type = ZS_FONT;
					fh = i;
					/* vector font については fh は vjfm の
					   リストの位置を示し、実際のﾌｧｲﾙﾊﾝﾄﾞﾙは
					   fh 番目の vjfm.font_no が示すfont_noの
					   vfont[font_no].v_fh にある。       */
					find_flg++;
					break;
				}
#ifdef BEZIERFONT
				/* JG font のオープン */
				if (open_vfont(font_no, (char *)tmp_buf, ".fn1", ".fn2", ".fn0")
					== TRUE) {
					vfont[font_no]->font_type = fontc->font_type = JG_FONT;
					fh = i;
					/* vector font については fh は vjfm の
					   リストの位置を示し、実際のﾌｧｲﾙﾊﾝﾄﾞﾙは
					   fh 番目の vjfm.font_no が示すfont_noの
					   vfont[font_no].v_fh にある。       */
					find_flg++;
					break;
				}
#endif
#ifdef TTFONT
				/* TrueType font のオープン */
				if ((open_vfont(font_no, (char *)tmp_buf, ".ttf", ".tti", NULL)
					 == TRUE) ||
					(open_vfont(font_no, (char *)tmp_buf, ".ttc", ".tti", NULL)
					 == TRUE)) {
					if (vfont[font_no]->v_fh[1] > 0) {
						vfont[font_no]->font_type = fontc->font_type = TT_FONT;
						get_ttinfo(font_no, vfont[font_no]->v_fh[1]);
						fh = i;
						find_flg++;
						break;
					}
				}
#endif

				vfont[font_no]->status = V_ERROR;
				error(WARNING, "[vfont] %s not found.", tmp_buf);
				/* vf1 file も fn1 file もなくて、ignore した場合には */
				/* ベクトルフォント・３次ベジェフォントは諦める       */
				return (NULL);
			}
		}
	}
def_knj:
#ifdef	USE_WINFONT
	switch(find_flg){
		case 0:
			if(check_wintt(fontc->n)){
				find_flg = 4;
				name = "edefault";
				goto subst;
			}
			org_name = name;
			find_flg = 2;
			name = (fontc->f_goth & F_TATE)?"tdefault":"default";
			goto subst;

		case 2:
			return NULL;

		case 3:
			error(WARNING, "Cannot find font file for %s!\n"
					   "A default FONT will be used.",
						org_name);
	}
#else
	if (!find_flg)
		return (NULL);
#endif
	/* define Kanji Font file */
	width = *wdthp;
	height = *hghtp;
	if (fontc->font_type == ZS_FONT
#ifdef BEZIERFONT
		|| fontc->font_type == JG_FONT
#endif
#ifdef TTFONT
		|| fontc->font_type == TT_FONT
#endif
#ifdef	USE_WINFONT
		|| fontc->font_type == WINJTT_FONT
#endif
		) {
		if (vfont[font_no]->width_adj != 1000)
			width = ((long)width * vfont[font_no]->width_adj) / 1000;
		if (vfont[font_no]->height_adj != 1000)
			height = ((long)height * vfont[font_no]->height_adj) / 1000;
		adj = 0;
#ifdef	USE_WINFONT
		*wdthp = width;
		*hghtp = height;
		if (fontc->font_type == WINJTT_FONT){
			if(vjfm->rotation & 1){
				static short int ss[]
					= {0, -33, -67, -100, -133, 0, 37, 83, 143, 222};

				if(vjfm->long_wide >= 'a' && vjfm->long_wide <= 'j')
					adj = ss[vjfm->long_wide - 'a'];
			}
			GetWinjTTMetric(vjfm, &width, &height, fontc->n);
			size  = height*vjfm->_xfat/1000;
			height = height*(vjfm->_yfat+adj)/1000;
			if(width > 0)
				goto set_knj;
			fontc->font_type = UNKNOWN;
			return NULL;
		}
#endif
		if ((int)'b' <= vjfm->long_wide
			&& vjfm->long_wide <= (int)'e') {
			height = (int)((long)width
						   * 10 / (10 - (vjfm->long_wide - (int)'a')));
		}
		else if ((int)'g' <= vjfm->long_wide
				 && vjfm->long_wide <= (int)'j') {
			height = (int)((long)width
						   * (10 - (vjfm->long_wide - (int)'f')) / 10);
		}
		if (vjfm->slant != (int)'a') {
			i = (vjfm->slant - (int)'b') % 3;
			if ((int)'b' <= vjfm->slant && vjfm->slant <= (int)'g') {
				width = (int)((long)width
							  * (MAX_VALUE + s_ratio[i]) / (MAX_VALUE + 1));

			}
			else {
				height = (int)((long)height
							   * (MAX_VALUE + s_ratio[i]) / (MAX_VALUE + 1));
			}
		}
	}
	*wdthp = width;
	*hghtp = height;
	size = (width + 7) / 8 * height;
set_knj:
	fontc->k_top = fontc;
	kf = (KFONT *)marea(KFONT_SIZE);
	kf->name = (char *)dup_string((char *)tmp_buf);
	kf->width = width;
	kf->height = height;
	kf->size = size;
	kf->fh = fh;
	return (kf);
}

/*************************************************************
*	open_vfont
*	ベクトルフォントのオープン
*	name.ext0 が存在しないときは (FAILURE) を返す
**************************************************************/
static int open_vfont(int font_no, char *name, 
		char *ext0, char *ext1, char *ext2)
{
	char v_name[MAXPATH], tmp1[MAXPATH+0x80], tmp2[MAXPATH+0x80];
	char *ext[3], *argv[3];
	int i, tmp_fh;

	if (vfont[font_no]->status == V_OPEN) return (TRUE);
	ext[0] = ext0;
	ext[1] = ext1;
	ext[2] = ext2;
	for (i = 0; i < 3; i++) {
		if (ext[i] != NULL) {
			if (vfont[font_no]->v_fh[i] == 0) {
				make_path(v_name, NULL, name, ext[i]);
				if ((tmp_fh = openf(v_name, O_RDONLY | O_BINARY)) > 0) {
					vfont[font_no]->v_fh[i] = tmp_fh;
				} else {
					if(i == 0) return (FAILURE);	/* ext0 が見つからない */
					if(i == 1 && !strcmp(ext1, ".tti")){
						SetPath(tmp2, v_name);
						sprintf(tmp1, 
							"Cannot find %s\nTry to make it?", tmp2);
						if(AskYes(tmp1,
						  "Make *.tti file for TrueType font")){
							make_path(tmp1, NULL, name, ext[0]);
							SetPath(tmp2, tmp1);
							argv[0] = "ttindex.exe";
							argv[1] = tmp2;
							argv[2] = NULL;
							WinMinExecute(argv, 0, TRUE);
							if ((tmp_fh = openf(v_name, O_RDONLY | O_BINARY)) > 0) {
								vfont[font_no]->v_fh[1] = tmp_fh;
								continue;
							}
						}
					}
					error(WARNING, "[vfont] %s not found.", v_name);
				}
			}
		}
	}
	vfont[font_no]->status = V_OPEN;
	return (TRUE);
}

/*************************************************************
*	flush_vfn
*	ファイルハンドルが足りないときに一時的にベクトルフォント
*	をクローズする．(fopenf(), openf() の下請け)
**************************************************************/
int flush_vfn(int number)
{
	static font_no;
	int i, j, count;

	if(number==0){
		font_no = 0;
		return 0;
	}
	for (i = count = 0; i < MAX_VFONT; i++) {
		if (vfont[font_no]->status == V_OPEN) {
			for (j = 0; j < 3; j++) {
				if (vfont[font_no]->v_fh[j] > 0) {
					close(vfont[font_no]->v_fh[j]);
					vfont[font_no]->v_fh[j] = 0;
					f_flush_pk++;
					count++;
				}
			}
			vfont[font_no]->status = V_FLUSH;
			if(count >= number)
				return( count );
		}
		font_no = (font_no + 1) % MAX_VFONT;
	}
	return( count );
}


#ifndef	NOTATEGAKI
/*************************************************************
*	TateKanji_type(unsigned int jms_char_code)
*   sjisr_codeより疑似縦書きのフォントの座標変換タイプを
*   決定さすための関数 (vdata.c にある)
**************************************************************/
void TateKanji_type(unsigned int);

#endif

#ifdef	USE_WINFONT
void set_wintt_preamble(int char_code, PREAMBLE *preamble, FONT_INFO *font, 
	char *name)
{
	GetWinjTTGlyph(get_vjfm(font->ext.kdir->fh), char_code, 
		font->k_height, preamble, 1, font->n);
}
#endif

/*************************************************************
*	get_vfont
*	char_codeのフォントをベクトルフォントで展開する
**************************************************************/
void get_vfont(int char_code, PREAMBLE *preamble, FONT_INFO *font)
{
	int font_no, jis_level;
	long size_bytes;
	int max_width, max_height, max_shift;
	unsigned sjis_code, utmp;
	KFONT *kf;
	BUFFER *buffer;
	V_JFM *vjfm;
	VPARA_TBL v_table;

	kf = font->ext.kdir;
	vjfm = get_vjfm(kf->fh);
	font_no = vjfm->font_no;
#if	defined(USE_WINFONT)
	if(vfont[font_no]->font_type == WINJTT_FONT){
		GetWinjTTGlyph(vjfm, char_code, font->k_height, preamble, 2, font->n);
		return;
	}
#endif
	sjis_code = jistojms(char_code);
	if (vfont[font_no]->status == V_FLUSH) {
	
	/* フラッシュされたベクトルフォントの再オープン */
		strcpy(tmp_buf, (char *)vfont[font_no]->v_font_name);
		if (vfont[font_no]->font_type == ZS_FONT) {
			if (open_vfont(font_no, (char *)tmp_buf, ".vf1", ".vf2", NULL)
				!=  TRUE) goto err_box;
#ifdef BEZIERFONT
		} else if (vfont[font_no]->font_type == JG_FONT) {
			if (open_vfont(font_no, (char *)tmp_buf, ".fn1", ".fn2", ".fn0")
				!=  TRUE) goto err_box;
#endif
#ifdef TTFONT
		} else if (vfont[font_no]->font_type == TT_FONT) {
			if ((open_vfont(font_no, (char *)tmp_buf, ".ttf", ".tti", NULL)
				 !=  TRUE) &&
				(open_vfont(font_no, (char *)tmp_buf, ".ttc", ".tti", NULL)
				 !=  TRUE)) goto err_box;
#endif
		} else {
			goto err_box;
		}
	}

#ifndef	NOTATEGAKI
	TateKanji_type(sjis_code);
#endif
	v_table.font_no = font_no;
	v_table.v_font_name = vfont[font_no]->v_font_name;
	v_table.font_type = vfont[font_no]->font_type;
	if (vfont[font_no]->yoffset == 0x400) {
		/* フォントの垂直方向オフセットを求める */
		/* STD_CODE('亜')を基準にする  */
		/* 第１水準 */
		v_table.vfn_file = vfont[font_no]->v_fh[0];	/* vf1 file */
		v_table.char_code = STD_CODE;
		utmp = STD_CODE - (
#ifdef BEZIERFONT
			(v_table.font_type == JG_FONT)?0x3000:
#endif
			0x2100);
		v_table.v_code = (utmp >> 8) * 0x5e + (utmp & 0xff) - 0x21;
		v_table.long_wide = (int)'a';
		v_table.slant = (int)'a';
		vfont[font_no]->yoffset = get_yofs(&v_table);
	}

	v_table.char_code = char_code;
	if (v_table.font_type == ZS_FONT) {			/* ZS_FONT */
		if (jisl2(sjis_code) != 0 || jislgaiji(sjis_code) != 0) {
			/* 第２水準 */
			jis_level = 1;
			utmp = char_code - 0x5000;
		} else {
				/* 第１水準 */
				jis_level = 0;
				utmp = char_code - 0x2100;
		}
	}
#ifdef BEZIERFONT
	else if (v_table.font_type == JG_FONT) {	/* JG_FONT */
		if (jisl2(sjis_code) != 0 || jislgaiji(sjis_code) != 0) {
			/* 第２水準 */
			jis_level = 1;
			utmp = char_code - 0x5000;
		} else if (jisl1(sjis_code) != 0) {
			/* 第１水準 */
			jis_level = 0;
			utmp = char_code - 0x3000;
		} else {
			/* 漢字以外の文字 */
			jis_level = 2;
			utmp = char_code - 0x2100;
		}
	}
#endif
#ifdef TTFONT
	else if (v_table.font_type == TT_FONT) {	/* TT_FONT */
		jis_level = vjfm->rotation = 0;
		utmp = char_code - 0x2100;
	}
#endif

	v_table.v_code = (utmp >> 8) * 0x5e + (utmp & 0xff) - 0x21;
	v_table.vfn_file = vfont[font_no]->v_fh[jis_level];

	if (preamble->rotate_ptex & 1){
		v_table.width = kf->height;
		v_table.height = kf->width;
	}
	else{
		v_table.width = kf->width;
		v_table.height = kf->height;
	}
	v_table.long_wide = vjfm->long_wide;
	v_table.slant = vjfm->slant;
	v_table.yoffset = vfont[font_no]->yoffset;
	v_table.thin = vjfm->thin;
	v_table.xfat = vjfm->_xfat;
	v_table.yfat = vjfm->_yfat;
	v_table.rotation = vjfm->rotation;

	max_width = MAX_VALUE;
	max_height = MAX_VALUE;
	max_shift = s_ratio[(v_table.slant - (int)'b') % 3];

	if ((int)'b' <= v_table.slant && v_table.slant <= (int)'g')
		max_width += max_shift;
	else if ((int)'h' <= v_table.slant && v_table.slant <= (int)'m')
		max_height += max_shift;

	v_table.max_width = max_width;
	v_table.max_height = max_height;

	size_bytes = (long)((v_table.width + 7) / 8) * v_table.height;
	v_table.buffer = buffer = preamble->raster;
	if (v_table.vfn_file == -1) {
		/* 第二水準フォントファイルがないのに，第二水準文字が使われた */
		error(WARNING, "[%sfont] JIS level 2 is used. %s(%XH)",
#ifdef BEZIERFONT
				(v_table.font_type == ZS_FONT)?"JG":
#endif
				"v",
				font->name, char_code);
		goto err_box;
	}

	bigbox(buffer, size_bytes, 0);

	if (vjfm->draw_sw == (int)'o')
		v_table.dtype = VTRACE;
	else if (vjfm->draw_sw == (int)'f')
		v_table.dtype = FILL;
	else
		v_table.dtype = BOTH;

#ifdef	USE_COLOR
	set_black(1);
#endif
	if (v_table.width < vjfm->threshold
#ifdef	VFTPIC
		|| !(f_tpic_turn_on&3)
# endif
	 ) {
		if (draw_fine(&v_table) == FAILURE)
			goto err_box;
	}
	else{  
		if (draw_character(&v_table) == FAILURE) 
err_box:	bigbox(buffer, size_bytes, 0xff);
#ifdef	USE_ETF
	if(f_make_jttetf && font->font_type == TT_FONT)
		SetETFindex(NULL, 0, 0, 0, 0, 3);
#endif
	}
#ifdef	USE_ETF
	if(f_make_jttetf && font->font_type == TT_FONT)
		SetETFindex(font, char_code, 0, 0, 0, 1);
#endif
#ifdef	USE_COLOR
	set_black(-1);
#endif
	free_vdata();
	free_vraster();
}

/* 疑似ゴシックモードの変更情報 Tomiie */
int chk_vfont_goth(FONT_INFO *font)
{
	KFONT *kf;
	V_JFM *vjfm;

	kf = font->ext.kdir;
	vjfm = get_vjfm(kf->fh);

	return vjfm->f_goth;
}

#ifdef TTFONT
#ifdef USE_ETF
extern CMTT_INFO cmetf_info;

/*************************************************************
*	埋めこみフォント中の和文 TT font を展開する
**************************************************************/
void get_ettfont(int char_code, PREAMBLE *preamble, FONT_INFO *font)
{
	long size_bytes;
	int max_width, max_height, max_shift;
	unsigned sjis_code, utmp;
	KFONT *kf;
	BUFFER *buffer;
	VPARA_TBL v_table;
	ETT_FONT *ett;

	ett = (ETT_FONT *)GetHoffset(font);
	kf = font->ext.kdir;

	sjis_code = jistojms(char_code);
#ifndef	NOTATEGAKI
	TateKanji_type(sjis_code);
#endif
	v_table.font_no = v_table.vfn_file = 0;
	v_table.v_font_name = NULL;
	v_table.font_type = ETF_FONT;
	utmp = char_code - 0x2100;
	v_table.char_code = char_code;
	v_table.v_code = (utmp >> 8) * 0x5e + (utmp & 0xff) - 0x21;
	if (preamble->rotate_ptex & 1){
		v_table.width = kf->height;
		v_table.height = kf->width;
	}
	else{
		v_table.width = kf->width;
		v_table.height = kf->height;
	}
	v_table.long_wide = ett->long_wide;
	v_table.slant = ett->slant;
	v_table.yoffset = ett->yoffset;
	v_table.thin = ett->thin;
	v_table.xfat = ett->_xfat;
	v_table.yfat = ett->_yfat;
	v_table.rotation = ett->rotation;
//	v_table.f_goth = ett->vj_f_goth;

	max_width = MAX_VALUE;
	max_height = MAX_VALUE;
	max_shift = s_ratio[(v_table.slant - (int)'b') % 3];

	if ((int)'b' <= v_table.slant && v_table.slant <= (int)'g')
		max_width += max_shift;
	else if ((int)'h' <= v_table.slant && v_table.slant <= (int)'m')
		max_height += max_shift;

	v_table.max_width = max_width;
	v_table.max_height = max_height;

	size_bytes = (long)((v_table.width + 7) / 8) * v_table.height;
	v_table.buffer = buffer = preamble->raster;

	if (ett->draw_sw == (int)'o')
		v_table.dtype = VTRACE;
	else if (ett->draw_sw == (int)'f')
		v_table.dtype = FILL;
	else
		v_table.dtype = BOTH;

	bigbox(buffer, size_bytes, 0);

#ifdef	USE_COLOR
	set_black(1);
#endif
	if (v_table.width < ett->threshold
#ifdef	VFTPIC
		|| !(f_tpic_turn_on&3)
# endif
	 ) {
		if (draw_fine(&v_table) == FAILURE)
			goto err_box;
	}
	else{  
		if (draw_character(&v_table) == FAILURE) 
err_box:	bigbox(buffer, size_bytes, 0xff);
	}
#ifdef	USE_COLOR
	set_black(-1);
#endif
	free_vdata();
	free_vraster();
}
#endif

/*************************************************************
*	get_cmttfont
*	欧文 TT font を展開する
**************************************************************/
void get_cmttfont(int char_code, PREAMBLE *preamble, FONT_INFO *font)
{
	VPARA_TBL v_table;
	BUFFER *buffer;
	CMTT_INFO far *cmtt_info;
	long size_bytes;

#ifdef	USE_ETF
	if(font->font_type == ETF_FONT){
		v_table.vfn_file = 0;
		cmtt_info = &cmetf_info;
	}else
#endif
	{
		if (font->ext.fh <= 0)
			font->ext.fh = openf(font->name, O_RDONLY | O_BINARY);
		v_table.vfn_file = font->ext.fh;
		cmtt_info = (CMTT_INFO far *)(font->pk + 4);
	}
	TateKanji_type(0x8169);
	v_table.buffer = buffer = preamble->raster;
	v_table.v_font_name = (BUFFER *)font->name;
	v_table.font_no = 0;
	v_table.char_code = v_table.v_code = char_code;
	v_table.max_width = ((cmtt_info->xMax - cmtt_info->xMin) * MAX_RANGE)
						/ cmtt_info->unitsPerEm;
	v_table.max_height = ((cmtt_info->yMax - cmtt_info->yMin) * MAX_RANGE)
						/ cmtt_info->unitsPerEm;
	v_table.width = preamble->width;
	v_table.height = preamble->height;
	v_table.yoffset = 0;
	v_table.long_wide = (int)'a';
	v_table.slant = (int)'a';
	v_table.thin = 100;
	v_table.xfat = 0;
	v_table.yfat = 0;
	v_table.font_type = font->font_type;
	v_table.rotation = 0;
	v_table.dtype = BOTH;
	size_bytes = (long)((v_table.width + 7) / 8) * v_table.height;
	bigbox(buffer, size_bytes, 0);
#ifdef	USE_COLOR
	set_black(1);
#endif
	if (f_use_ttf == 1 || sptopixel(font->size_para) <= f_use_ttf
#ifdef	VFTPIC
		|| !(f_tpic_turn_on&3)
# endif
	) {
		if (draw_fine(&v_table) == FAILURE)
			goto err_box;
	} else 	{
		if (draw_character(&v_table) == FAILURE)
err_box:	bigbox(buffer, size_bytes, 0xff);
#ifdef	USE_ETF
	if(f_make_etf)
		SetETFindex(NULL, 0, 0, 0, 0, 3);
#endif
	}
#ifdef	USE_ETF
	if(f_make_etf)
		SetETFindex(font, char_code, 0, 0, 0, 0);
#endif
#ifdef	USE_COLOR
	set_black(-1);
#endif
	free_vdata();
	free_vraster();
}
#endif

/*************************************************************
*	bbox
*	フォントバッファを塗りつぶす	未使用
**************************************************************/
/*void bbox(BUFFER *buffer, int size)
{
	int i;

	for (i = 0; i < size; i++)
		buffer[i] = 0xff;
}*/

/*************************************************************
*	bigbox
*	フォントバッファを値で塗りつぶす
**************************************************************/
static void bigbox(BUFFER *buffer, long size, int p)
{
	int i;
	HUGE_BUF *hbuffer;

	if (size < 0x7fff ) {
		for (i=size-1; i>=0; i--)
			buffer[i]=p;
	}
	else {
		for (hbuffer = buffer; size > 0; size--)
			*(hbuffer++) = p;
	}
}

#ifndef	CC_JPN
/*************************************************************
*	jistojms
**************************************************************/
unsigned short jistojms(unsigned short c)
{
	int hi, lo;

	hi = (c >> 8) & 0xFF;
	lo = c & 0xFF;
	if (hi & 1)
		lo += 0x1f;
	else
		lo += 0x7d;
	hi = ((hi - 0x21) >> 1) + 0x81;
	if (lo >= 0x7f)
		lo++;
	if (hi > 0x9f)
		hi += 0x40;
	return ((hi << 8) | lo);
}

/*************************************************************
*	jisl1, jisl2
**************************************************************/
#ifdef BEZIERFONT
static int jisl1(unsigned short c)
{
	return (0x889F <= c) && (c <= 0x9872);
}
#endif

static int jisl2(unsigned short c)
{
	return (0x989F <= c) && (c <= 0xEA9E);
}

/*************************************************************
*	jislgaiji
**************************************************************/
static int jislgaiji(unsigned short c)
{
	return (0xEA9F <= c) && (c <= 0xEFFC);
	/* EFFC = JIS:7E7E */
}

#endif

#ifdef VFTPIC
/*************************************************************
*	draw_character
*	tpicでベクトルフォントを展開する by Oh-Yeah?氏
*		modified by T.Minagawa
**************************************************************/
int draw_character(VPARA_TBL *tbl_ptr)
{
	int y_factor = (tbl_ptr->width + 7) / 8;
	/* linewidth of font raster map */
	double gray = (double)(tbl_ptr->thin + 1) / 100;

	/* meaning changed to grayscale (0 - 1). negative value means zero */
	int x, y, h;
	int vcorrection, itemno;
	pixelpoint ptop, p1, p2;
	Line *c_line;

	linecount = itemcount = 0;
	linebuf_end = linebuf;

	if (readdata(tbl_ptr, STD_MODE) == FAILURE)
		return (FAILURE);
	if (linecount == 0) return (TRUE);

	if (tbl_ptr->rotation == 0 
		 /* && !tategaki && !ptex_mode */ ) {
		/* 回転したときは処理が面倒なので y offset の調整は省略 ? */
		vcorrection = tbl_ptr->yoffset;
		for (h = 0, c_line = linebuf; c_line < linebuf_end; c_line++) {
			c_line->yu += vcorrection;
			h = max(h, c_line->yu - (tbl_ptr->max_height + 1));
		}
		if (h > 0) {
			for (c_line = linebuf; c_line < linebuf_end; c_line++)
				c_line->yu -= h;
		}
	}

	freeze_tpic_status();
	/* Note: It is assumed that
			(a) path stack is not used here, so it will not be frozen.
			(b) visible array, y-buckets and pixel stack are used immediately
				both here and in tpic.c, so they will not be frozen.
			(c) tpic rotation (rt) is not used here, so rotation matrix and
				flag will not be frozen.
		if not, rewrite freeze and melt functions in tpic.c. */
	init_alter_bitmap(tbl_ptr->buffer, y_factor);
	/* tricky: alter tpic destination bitmap to font raster data */
	/* Note: Be careful, width & height will not be checked in bitmap.c */
	set_pensize((TPIC_MI) 1);
	/* pensize = unit pixel. if not, this should be modified! */
	/* because tpic_pa cannot fill a doughnut, more primitive functions
	should be used ... (:_;) */
	switch (tbl_ptr->dtype) {
	  case VTRACE:				/* trace outline */
		  set_visible(1, 0);	/* all visible */
		  break;
	  case FILL:				/* fill interior */
		  set_visible(0, 1);	/* all invisible */
		  set_grayscale(gray);
		  break;
	  case BOTH:				/* trace and fill */
		  set_visible(1, 0);	/* all visible */
		  set_grayscale(gray);
		  break;
	}

	itemno = linebuf[0].itemno;
	x = linebuf[0].xl;
	y = linebuf[0].yu;
	ptop = p1 = vf_to_abs(tbl_ptr, x, y);
	for (c_line = linebuf + 1; c_line < linebuf_end; c_line++) {
		x = c_line->xl;
		y = c_line->yu;
		if (itemno != c_line->itemno) {
			rasterize_line(p1, ptop, FALSE, FALSE);	/* assure it is closed */
			p1 = vf_to_abs(tbl_ptr, x, y);
			ptop = p1;
			itemno = c_line->itemno;
		}
		else {
			rasterize_line(p1, p2 = vf_to_abs(tbl_ptr, x, y), FALSE, FALSE);
			p1 = p2;
		}
	}
	rasterize_line(p1, ptop, FALSE, FALSE);	/* assure it is closed */

	if (tbl_ptr->dtype != VTRACE)
		raster_fill();
	raster_draw();
	clean_bucket();

	fin_alter_bitmap();			/* recover original bitmap */
	melt_tpic_status();			/* recover tpic static variables */
	return (TRUE);
}

/*************************************************************
*	vf_to_abs
**************************************************************/
static pixelpoint vf_to_abs(VPARA_TBL *tbl_ptr, int x, int y)
{	   /* convert font coord to bitmap coord */
	pixelpoint p;

	p.x = (int)(
				   ((long)x * tbl_ptr->width - (tbl_ptr->max_width + 1) / 2)
				   / (tbl_ptr->max_width + 1));
	p.y = (int)(
				 ((long)y * tbl_ptr->height - (tbl_ptr->max_height + 1) / 2)
					/ (tbl_ptr->max_height + 1));
	return (p);
}

#else /* if VFTPIC is not defined... */

/*************************************************************
*	draw_character
*     Original routine of vector font rasterizer.
**************************************************************/
int draw_character(VPARA_TBL *tbl_ptr)
{
	int x, y, x0, y0, x1, y1, h, j;
	int vcorrection, itemno, funcno;
	Line *c_line;

	/*	static void_func_ptr draw_func[]( VPARA_TBL*, int, int, int, int ) = {*/
	static void (*draw_func[]) (VPARA_TBL *, int, int, int, int) =
	{
		fill_edges,
		trace_outline
	};

	linecount = itemcount = 0;
	linebuf_end = linebuf;

	if (readdata(tbl_ptr, STD_MODE) == FAILURE)
		return (FAILURE);

	vcorrection = tbl_ptr->yoffset;
	for (h = 0, c_line = linebuf; c_line < linebuf_end; c_line++) {
		c_line->yu += vcorrection;
		h = max(h, c_line->yu - (tbl_ptr->max_height + 1));
	}
	if (h > 0) {
		for (c_line = linebuf; c_line < linebuf_end; c_line++)
			c_line->yu -= h;
	}

	switch (tbl_ptr->dtype) {
	  case VTRACE:				/* trace outline */
		  h = 0;
		  j = 1;
		  break;
	  case FILL:				/* fill interior */
		  h = 1;
		  j = 2;
		  break;
	  case BOTH:				/* trace and fill */
		  h = 0;
		  j = 2;
		  break;
	}

	itemno = linebuf[0].itemno;
	x0 = x1 = linebuf[0].xl;
	y0 = y1 = linebuf[0].yu;
	for (funcno = h; funcno < j; funcno++) {
		for (c_line = linebuf; c_line < linebuf_end; c_line++) {
			x = c_line->xl;
			y = c_line->yu;
			if (itemno != c_line->itemno) {
				draw_func[funcno] (tbl_ptr, x1, y1, x0, y0);
				x0 = x1 = x;
				y0 = y1 = y;
				itemno = c_line->itemno;
			}
			else {
				draw_func[funcno] (tbl_ptr, x1, y1, x, y);
				x1 = x;
				y1 = y;
			}
		}
		draw_func[funcno] (tbl_ptr, x1, y1, x0, y0);
	}

	return (TRUE);

}

/*************************************************************
*	trace_outline
*     Original routine of vector font rasterizer.
**************************************************************/
static void trace_outline
	(VPARA_TBL *tbl_ptr, int x1, int y1, int x2, int y2) {
	int dx, dy, dx2, dy2, e, i, tmp;
	BUFFER *address;
	BUFFER *buffer = tbl_ptr->buffer;
	int width = tbl_ptr->width;
	int height = tbl_ptr->height;
	int max_width = tbl_ptr->max_width;
	int max_height = tbl_ptr->max_height;
	int thin = tbl_ptr->thin;
	int y_factor = (width + 7) / 8;

	unsigned char mask;
	long offset_x, minus_offset_x, plus_offset_x;
	long offset_y, minus_offset_y, plus_offset_y;

	offset_x = (long)thin *(max_width + 1) / 100l / 2l;

	minus_offset_x = -(max_width + 1) / 2l - offset_x;
	plus_offset_x = -(max_width + 1) / 2l + offset_x;
	offset_y = (long)thin *(max_height + 1) / 100l / 2l;

	minus_offset_y = -(max_height + 1) / 2l - offset_y;
	plus_offset_y = -(max_height + 1) / 2l + offset_y;

	dx = x2 - x1;
	dy = y2 - y1;
	if (dy < 0) {
		x1 = (int)(((long)x1 * width + minus_offset_x) / (max_width + 1));
		x2 = (int)(((long)x2 * width + minus_offset_x) / (max_width + 1));
	}
	else if (dy == 0) {
		x1 = (int)(((long)x1 * width - (max_width + 1) / 2) / (max_width + 1));
		x2 = (int)(((long)x2 * width - (max_width + 1) / 2) / (max_width + 1));
	}
	else {
		x1 = (int)(((long)x1 * width + plus_offset_x) / (max_width + 1));
		x2 = (int)(((long)x2 * width + plus_offset_x) / (max_width + 1));
	}
	if (dx > 0) {
		y1 = (int)(((long)y1 * height + minus_offset_y) / (max_height + 1));
		y2 = (int)(((long)y2 * height + minus_offset_y) / (max_height + 1));
	}
	else if (dx == 0) {
		y1 = (int)(((long)y1 * height - (max_height + 1) / 2)
				   / (max_height + 1));
		y2 = (int)(((long)y2 * height - (max_height + 1) / 2)
				   / (max_height + 1));
	}
	else {
		y1 = (int)(((long)y1 * height + plus_offset_y) / (max_height + 1));
		y2 = (int)(((long)y2 * height + plus_offset_y) / (max_height + 1));
	}
	if (x1 < 0)
		x1 = 0;
	else if (x1 >= max_width)
		x1 = max_width - 1;
	if (x2 < 0)
		x2 = 0;
	else if (x2 >= max_width)
		x2 = max_width - 1;
	if (y1 < 0)
		y1 = 0;
	else if (y1 >= max_height)
		y1 = max_height - 1;
	if (y2 < 0)
		y2 = 0;
	else if (y2 >= max_height)
		y2 = max_height - 1;

	dy = y2 - y1;
	if (dy < 0) {
		tmp = x1;
		x1 = x2;
		x2 = tmp;
		tmp = y1;
		y1 = y2;
		y2 = tmp;
		dy = -dy;
	}
	dx = x2 - x1;
	if (dx < 0)
		dx = -dx;
	if (dx == 0 && dy == 0)
		return;
	address = &buffer[y1 * y_factor + x1 / 8];
	mask = 0x80 >> (x1 & 7);
	dx2 = 2 * dx;
	dy2 = 2 * dy;

	if (dx < dy) {
		e = dx2 - dy;
		if (x1 < x2) {
			for (i = 0; i <= dy; i++) {
				*address |= mask;
				while (e >= 0) {
					if ((mask >>= 1) == 0) {
						address++;
						mask = 0x80;
					}
					e -= dy2;
				}
				address += y_factor;
				e += dx2;
			}
		}
		else {
			for (i = 0; i <= dy; i++) {
				*address |= mask;
				while (e >= 0) {
					if ((mask <<= 1) == 0) {
						address--;
						mask = 0x1;
					}
					e -= dy2;
				}
				address += y_factor;
				e += dx2;
			}
		}
	}
	else {
		e = dy2 - dx;
		if (x1 < x2) {
			for (i = 0; i <= dx; i++) {
				*address |= mask;
				while (e >= 0) {
					address += y_factor;
					e -= dx2;
				}
				if ((mask >>= 1) == 0) {
					address++;
					mask = 0x80;
				}
				e += dy2;
			}
		}
		else {
			for (i = 0; i <= dx; i++) {
				*address |= mask;
				while (e >= 0) {
					address += y_factor;
					e -= dx2;
				}
				if ((mask <<= 1) == 0) {
					address--;
					mask = 0x1;
				}
				e += dy2;
			}
		}
	}
}

/*************************************************************
*	fill_edges
*     Original routine of vector font rasterizer.
**************************************************************/
static void fill_edges
	(VPARA_TBL *tbl_ptr, int x1, int y1, int x2, int y2) {
	static unsigned char mask_pattern[8] =
	{0xff, 0x7f, 0x3f, 0x1f, 0xf, 0x7, 0x3, 0x1};
	int dx, dy, dx2, dy2, sx, e, i, j, tmp;
	int width = tbl_ptr->width;
	int height = tbl_ptr->height;
	int max_width = tbl_ptr->max_width;
	int max_height = tbl_ptr->max_height;
	int y_factor = (width + 7) / 8;
	BUFFER *address;
	BUFFER *buffer = tbl_ptr->buffer;
	int bit, right_bytes;

	x1 = (int)(((long)x1 * width - (max_width + 1) / 2)
			   / (max_width + 1));
	y1 = (int)(((long)y1 * height - (max_height + 1) / 2)
			   / (max_height + 1));
	x2 = (int)(((long)x2 * width - (max_width + 1) / 2)
			   / (max_width + 1));
	y2 = (int)(((long)y2 * height - (max_height + 1) / 2)
			   / (max_height + 1));

	dy = y2 - y1;
	if (dy == 0)
		return;
	if (dy < 0) {
		tmp = x1;
		x1 = x2;
		x2 = tmp;
		tmp = y1;
		y1 = y2;
		y2 = tmp;
		dy = -dy;
	}
	dx = x2 - x1;
	sx = dx > 0 ? 1 : -1;
	if (dx < 0)
		dx = -dx;
	address = &buffer[y1 * y_factor + x1 / 8];
	right_bytes = (width - 1) / 8 - x1 / 8;
	bit = x1 & 7;
	dx2 = 2 * dx;
	dy2 = 2 * dy;
	e = dx2 - dy;

	for (i = 0; i < dy; i++) {
		/* Change right bits in this byte. */
		*address ^= mask_pattern[bit];
		/* Change all the bits in right bytes. */
		for (j = 1; j <= right_bytes; j++) {
			address[j] = ~address[j];
		}
		while (e >= 0) {
			bit += sx;
			if (bit & 0x8) {
				address += sx;
				right_bytes -= sx;
				bit &= 0x7;
			}
			e -= dy2;
		}
		address += y_factor;
		e += dx2;
	}
}

#endif /* end of ifdef VFTPIC ... else ... */

/* end of all */
