/*
 *  TEX Device Driver  ver 2.02-
 *  copyright(c) 1988, 1989 by TSG, 1990-93 by SHIMA
 *  1991 changed by hideki
 *  1991 changed by T.Minagawa
 *
 *  getfont.c : get unpacked font
 *
 *  Apr. 15, 1989 : first edition
 *  Jul.  2, 1989 : 2nd edition
 *	modified for non PC-9801 machines by sempa 1992
 *	very slightly modified against warnings by Oh-Yeah? 25 May 1992
 *  modifed for LIPS3 by SHIMA 30 June 1992
 *	modified for pTeX (tate mode) by Naochan! 6 August 1992
 *  slightly modified for pTeX on LIPS3 by OkI 8 August 1992
 *  modified  by Tomiie 20 August 1992
 *	modified for LIPS3+ESC/Page by OkI & H.Tomiie 30 Sept. 1992
 *  slightly modified for JGfont(3D-Bezier) by Naochan! 12 November 1992
 *  modified to use EMS by SHIMA 13 Dec 1992
 *  slightly modified for NTTjTeX by Yakumo 24 Dec. 1992
 *  modified to use font with magnification and reduction;
 *           by Yoshizawa, Matsuda, SHIMA, Naochan! 22 Feb. 1993
 *
 * DOS/V の24x24 dot font の読みだしをサポート　1994/07/24
 *           by h.senshu
 */

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

#ifdef	UNIX
#include <unistd.h>
#else
#include <io.h>
#include <ctype.h>
#ifndef	GCC1
#ifdef MSVC
#include <memory.h>
#include <malloc.h>
#include "msvcdir.h"
#else
#include <mem.h>
#include <alloc.h>
#include <dir.h>
#endif
#else
#include <djgppstd.h>
#endif
#endif

#define _DEF_STDIO_H_
#include "dd.h"
#include "err.h"
#include "buffer.h"
#include "dviread.h"
#include "inter.h"
#include <fcntl.h>

#ifdef TTFONT
#include "ttfont.h"
#endif

#ifdef	USE_WINFONT
#include "vfont.h"
void  ResetWinTTCache(void);
#endif

#ifdef	USE_SUBFONT
#include "subfont.h"
#endif

#define	BIG_ZS	1

#define	CHAR_SIZE	16
#define	KCG_BUF		32

#define PK_PRE		247
#define PK_ID		89
#define	PKD_ID		('p'+'k'+'d')
#define PK_POST		245
#define VFD_PRE		'v'
#define VFD_ID		('f'+'d')
#define VFDW_ID		((VFD_ID<<8)+VFD_PRE)

#define	PKW_ID		((PK_ID<<8)+PK_PRE)
#define	PKDW_ID		(((PKD_ID & 0xff)<<8)+PK_PRE)
#define	PXL1001_ID	(3+(233<<8))
#define	PXL1002_ID	(3+(234<<8))
#define	PXL1003_ID	(3+(235<<8))
#define	JXL4_0_ID	(0x0100)
#define	JXL4_1_ID	(0x258B)
#define	JTFM_ID		(11<<8)
#define JTFMP_ID    (9<<8)		/* this definition is used in LBP.C, too */
#define	CMTTF_ID	('t' + 't' + 'f')
#define	VIRTUALFONT_ID	(0xCAF7)	/* 247(pre), 202(id) */

#define	BASE_RATIO	151

/* prtsize.c */
extern long sp_per_pxl;

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

 /* decodepk.c */
void decode_pk(BUFFER *, PREAMBLE *, int, FONT_INFO *);
void decode_jxl(BUFFER *, PREAMBLE *, int, FONT_INFO *);
void decode_vfn(int, BUFFER *, PREAMBLE *, FONT_INFO *);

 /* loadpk.c */
BUFFER *load_pk(char *, char *);
int ask_pk_buf(long);
void re_openf(FONT_INFO *);
int openf(char *, int);

 /* raster.c */
void raster_buf_alloc(PREAMBLE **, long);
void cut_raster(uint);
PREAMBLE *alloc_preamble(void);

 /* bitmap.c */
extern int f_shift_EMS;
BUFFER *rotate_raster(PREAMBLE *);

 /* sptopxl.asm  */
PIXEL sptopixel(SCALED_PT);
PIXEL vtopixel(SCALED_PT);

 /* mult20.asm */
SCALED_PT mult20(SCALED_PT, SCALED_PT);

 /* fontdef.c */
KFONT *open_kfont(FONT_INFO *, int, int, JFM_DATA *);
void open_pk(FONT_INFO *);
void open_jxl(FONT_INFO *);
void open_vf(FONT_INFO *);
int chk_goth(FONT_INFO *);
void resolve_font(FONT_INFO *);

/* pret.c */
void rewrite_preamble_ptex(PREAMBLE *, uint, FONT_INFO *);
uint ntt_to_jis(uint, int);

/* vfont.c */
void set_wintt_preamble(int, PREAMBLE *, FONT_INFO *);
unsigned short jistojms(unsigned short);
extern V_JFM *v_tfm;

#ifndef	NOVFONT
int chk_vfont_goth(FONT_INFO *);

#endif
char *get_font_name(FONT_INFO *);

 /* loadpk.c */
int file_read(int, BUFFER *, int);
FILE *fopenf(char *name, char *mode);

 /* vfont.c */
void get_vfont(int, PREAMBLE *, FONT_INFO *);
char *check_ftt(char *);
#ifdef TTFONT
void get_cmttfont(int, PREAMBLE *, FONT_INFO *);
void get_ettfont(int, PREAMBLE *, FONT_INFO *);
#endif

#ifdef BEZIERFONT
 /* jgfont.c */
void get_bezfont(int, PREAMBLE *, FONT_INFO *);
#endif
#ifdef TTFONT
void ttf_metrics(FONT_INFO *, int, PREAMBLE *);
#endif
#ifdef USE_ETF
void etf_metrics(unsigned char **, FONT_INFO *, int, PREAMBLE *);
extern BOOL f_make_pketf;
extern BOOL f_make_vfetf;
extern BOOL f_make_mapetf;
#endif

#ifdef	LBP
int search_djtable(uint code, uint font_code);
#endif

#ifdef	VIRTUALFONT
/* virfont.c */
BUFFER *get_virtualfont(FONT_INFO *, int, int *);
long virtualfont_tfm_width(BUFFER *, int, int);
BOOL load_character_packet(BUFFER *, int, PREAMBLE *);
#endif

/* #ifdef	WIN32 */
int k_scale = 1000;
/* #else */
/* int k_scale = 952; */
/* #endif */
int k_base = 0;
BOOL f_ktbase = TRUE;
static int f_get_pk = 0;
BOOL f_font_c;
BOOL f_kglue;
#ifdef	WIN32G
static int f_propw;
void CheckPropw(BOOL);
#endif

#if	defined(FDOWN)
int f_assigned;
#endif

extern char *goth;
extern int g_font;
extern CHAR_INFO *char_info_ptr;
extern int test_flg;
extern int enlarge;
extern char ptex_d;
extern BOOL f_resize;
extern int f_sub_blank;

#ifdef	FDOWN
extern int f_download;
extern uint dj_current;
extern int f_gaiji;
#endif

PREAMBLE *get_font(uint *, FONT_INFO *);
static long jtfm_width(FONT_INFO *, int);
long tfm_width(BUFFER *, int);
void set_trans_jis(char *);
static uint trans_jis(uint);
static BUFFER *get_pk(int, FONT_INFO *, int *);
static void get_knjpk(int, PREAMBLE *, FONT_INFO *);
static int read_flag_byte(BUFFER **);
static PREAMBLE *set_preamble(BUFFER **, int *, FONT_INFO *, int);
static void get_kfont(int, PREAMBLE *, FONT_INFO *);
static void exp_1001(BUFFER *, PREAMBLE *, FONT_INFO *);
static void exp_1002(BUFFER *, PREAMBLE *, FONT_INFO *);
static void exp_1003(BUFFER *, PREAMBLE *, FONT_INFO *);
static void font_dbl(PREAMBLE *);
static BUFFER *get_pkd(FONT_INFO *, long, int *);
static BUFFER *get_jxl(long far *, FONT_INFO *, long, int *);
static void resize_getfont(PREAMBLE *, int, int);
static void rotate_getfont(PREAMBLE *);

#ifdef VFD
static BUFFER *get_vfd(FONT_INFO *, long, int);
#endif

#ifndef NO_NTTRPL
/* 6,7,8,9,10,11,12,17,20pt の DNP-fontのサイズ*/
static const long nttf_width[9] =
{0xec673L, 0xeddf1L, 0xe7439L, 0xe8fa2L,
 0xea58fL, 0xea58fL, 0xec673L, 0xef6d1L, 0xea58fL};
static const long nttf_height[9] =
{0xc34a2L, 0xcaa19L, 0xb902dL, 0xbfdd0L,
 0xc5586L, 0xc5586L, 0xc34a2L, 0xc7859L, 0xc2430L};
static const long nttf_depth[9] =
{0x291d1L, 0x233d7L, 0x2e40bL, 0x291d1L,
 0x25009L, 0x25009L, 0x291d1L, 0x27e78L, 0x2815fL};
static void unify_nttjfont(FONT_INFO *);
#endif

JFM_DATA *jfm_read(FONT_INFO *font, int char_code);

static void resizefont(uchar *, uint, uint, PREAMBLE *);
													/* ROM FONT の拡大縮小 */
#if DEBUG & MEM_CHK
static void _pkptrchk(BUFFER *);

#endif

#define	expand_char_info_list( )	char_info_ptr

#ifdef BC31
#pragma option -3
#endif

struct TRANS_TABLE {
	uint org;
	uint new;
	char flag;
};

static struct TRANS_TABLE *trans_table;
static int total_trans;
#define	JIS_NO_TATE	2
#define	JIS_NO_YOKO	1

void set_trans_jis(char *pt)
{
	int i;
	total_trans = (int)strtol(pt, &pt, 0);
	Free0(trans_table);
	trans_table = (total_trans > 0)?
		(void *)marea(total_trans*sizeof(struct TRANS_TABLE)):NULL;
	pt++;

	for(i = 0; i < total_trans; i++){
		if(sscanf(pt, "%x=%x", &(trans_table[i].new), &(trans_table[i].org))
			!= 2 ) goto err;
		pt += 9;
		switch(*pt++){
			case 'y':
					trans_table[i].flag = JIS_NO_TATE;
					pt++;
					break;

			case 't':
					trans_table[i].flag = JIS_NO_YOKO;
					pt++;
					break;

			case  0 :
					if (i < total_trans - 1) goto err;
			case ':':
					trans_table[i].flag = 0;
					break;

			default:
err:		error(ILLEGAL_ARGS, "Bad parameter in -JC");
				total_trans = 0;
				Free(trans_table);
		}
	}
}


static uint trans_jis(uint char_code)
{
	int i;
	struct TRANS_TABLE *pt_table;

	if(char_code > 0xff){
		for(i = 0, pt_table = trans_table; i++ < total_trans; pt_table++){
			if(pt_table->org == char_code && pt_table->flag != ptex_d + 1)
				return(pt_table->new);
		}
	}
	return(char_code);
}

#ifdef	WIN32G
void SetPropw(int mode)
{
	static char *para;
	FONT_INFO	*font;
	int	len;

	if(mode == 2){
		if(para || f_propw)
			mode = 0;
		else
			mode = 1;
	}
	if(mode){
		if(!f_propw){
			if(mode == 1){
				if(GetXDpi() < 1000){
					for (font = first_font_info; font; font = font->next_font){
						if(font->font_type <= ONDEMAND2)
							resolve_font(font);
						len = strlen(font->name) - 4;
						if(len <= 0 || strcmp(font->name + len, ".tfm")){
							error(WARNING, "Non-TrueType fonts exists.");
							return;
						}
					}
					para = MareaPara("dpi y", 1);
					SetPara("-y=A7 -dpi=1925", SET_OPTION);
				}
			}
			f_propw = 1;
			CheckPropw(TRUE);
		}
	}else{
		f_propw = 0;
		if(para){
			MareaPara(para, -1);
			para = NULL;
		}
		CheckPropw(FALSE);
		error(DATATITLE, "Width of Japanese characters of TrueType");
	}
}
#endif

/* extern BOOL f_dviprt; */

PREAMBLE *get_font(uint *pt_code, FONT_INFO *font)
	/*  char_codeのフォントを得る．
	 */
{
	PREAMBLE *preamble;
	BUFFER *pk;

	uint char_code, new_code;
	int flag_byte, flag_nf, n_flush;
	int win_off;
	int new_width, new_height, f_modify;
	CHAR_INFO *char_info;
	CHAR_INFO *new_info;
	CHAR_INFO *kc_info;
	FONT_INFO *fontk;
	long	raster_size, tmp;
	JFM_DATA *jtfm;

#define	f_SIZE		1
#define	f_KSIZE		2
#define	f_ROTATE	4
#define	f_NOSAVE	8

	ENTER("get_font");
#if	defined(FDOWN)
	f_assigned =
#endif
	flag_nf = 0;
	char_code = *pt_code;

#if 0
	if(font->font_type <= UNRESOLVE){
		if(font->font_type == ONDEMAND){
			resolve_font(font);
			char_code = *pt_code = ntt_to_jis(char_code, font->code_offset);
		}else if(font->font_type == ONDEMAND2){
			resolve_font(font);
			if(font->font_type == UNRESOLVE)
			return NULL;
		}
		if(font->font_type == UNRESOLVE)
			exit(1);
	}
#endif
#ifdef	LBP
	if(font->font_type == JLBP)
		*pt_code = trans_jis(char_code);
# ifdef	JDWN
	else if(f_download > 2 && dj_current > 0){
		if (font->font_type == JXL || font->font_type >= ROM_FONT){
			if (search_djtable(char_code, font->font_code))
				f_assigned = 2;
		}
	}
# endif
#endif
#ifdef	FDOWN
	if ((font->f_goth & F_DWN) /* && f_dviprt */
		&& ((font->d_flag[char_code >> 3] & (1 << (char_code & 7)))))
		f_assigned = 1;
#endif
	if (font->font_type == JXL && (font->f_goth & F_TOPT) && !ptex_d){
			/* This does not occur when f_jdwn (<- dj_count > 0) */
		font->f_goth &= ~F_TOPT;
		n_flush = CHAR_ROOT;
		while(!n_flush) font->char_info[--n_flush] = NULL;
	}

	if ((char_info = font->char_info[char_code & (CHAR_ROOT - 1)]) != NULL) {
		/*  既に展開されたfontかどうか？
				 */
		if (char_info->code == char_code)
			RETURN(&(char_info->pre));
		for (;;) {
			if (char_info->code < char_code) {
				if (char_info->next_char == NULL) {
					flag_nf = 1;
					break;
				}
				if ((char_info = char_info->next_char)->code == char_code)
					RETURN(&(char_info->pre));
			}
			else {
				if (char_info->former_char == NULL) {
					flag_nf = -1;
					break;
				}
				if ((char_info = char_info->former_char)->code == char_code)
					RETURN(&(char_info->pre));
			}
		}
	}
	pk = get_pk(new_code = *pt_code = trans_jis(char_code), font, &flag_byte);
	n_flush = raster_buf_pointer->flush;
	preamble = set_preamble(&pk, &flag_byte, font, new_code);
	f_modify = 0;
#ifdef	LBP
	if (font->font_type == JLBP)
		goto c_inf;
#endif

	if (font->font_type >= JIS_FONT || font->font_type == ROM_FONT) {
		for (fontk = font->k_top; fontk; fontk = fontk->k_next) {
			if (fontk == font
				|| (kc_info = fontk->char_info[char_code & (CHAR_ROOT - 1)])
				== NULL)
				continue;
			if (kc_info->code == char_code) {
k_found:		preamble->raster = kc_info->pre.raster;
				goto c_inf;
			}
			for (;;) {
				if (kc_info->code < char_code) {
					if (kc_info->next_char == NULL)	break;
					if ((kc_info = kc_info->next_char)->code == char_code)
						goto k_found;
				}
				else {
					if (kc_info->former_char == NULL) break;
					if ((kc_info = kc_info->former_char)->code == char_code)
						goto k_found;
				}
			}
		}
	}
	raster_size = (long)preamble->byte_width*preamble->height;
	if (font->font_type == JXL && (font->f_goth & F_TOPT)){
		f_modify |= f_ROTATE;
		tmp = (long)((preamble->height+7)/8)*preamble->width;
		if(tmp > raster_size) raster_size = tmp;
	}
	if(  font->n[MAX_NAME_LEN-1] == '+'
	  && font->dpi != font->sdpi
	  && (font->font_type <= JXL || font->font_type == ETF_FONT)){
		tmp = font->dpi*1000/font->sdpi;
		if(enlarge && font->f_goth & K_SCALE)
			tmp = tmp*enlarge/1000;
			goto scale;
	}
	if (font->f_goth & K_SCALE){
		if (font->font_type > SUBTFM){
			f_modify |= f_KSIZE;
			if ((font->f_goth & F_TATE) && !(preamble->rotate_ptex & 1)){
				new_width  = font->k_height;
				new_height = font->k_width;
			}
			else{
				new_width  = font->k_width;
				new_height = font->k_height;
			}
			tmp = (long)(new_width+7)/8*new_height;
			goto cmp_size;
		}
		else{
			tmp = enlarge;
scale:		preamble->pitch_offset 
						= ((long)preamble->pitch_offset*tmp+500)/1000;
			preamble->depth_offset
						= ((long)preamble->depth_offset*tmp+500)/1000;
			if(!(new_width  = ((long)preamble->width*tmp+500)/1000))
				new_width = 1;
			if(!(new_height = ((long)preamble->height*tmp+500)/1000))
				new_height = 1;
			if (new_width != preamble->width
			  || new_height != preamble->height){
				f_modify |= f_SIZE;
				if (tmp > 1000){
					if(f_modify & f_ROTATE){
						tmp = (long)((new_height+7)/8) * new_width;
cmp_size:				if (tmp > raster_size) raster_size = tmp;
					}else
						raster_size = (long)((new_width+7)/8) * new_height;
				}
			}
		}
	}
#ifdef	VIRTUALFONT
	if (font->font_type == VIRTUAL_FONT) {
		/* load a character packet instead of bitmap */
		if (load_character_packet(pk, flag_byte, preamble) == TRUE){
#ifdef	USE_ETF
			if(f_make_vfetf){
				tmp = (pk - font->pk) + ((flag_byte == 242)?12:4);
				SetETFindex(font, char_code, 0, 
					tmp, tmp + preamble->byte_width - 1, 0);
			}
#endif
			goto c1_inf;
		}
	}
#endif
	raster_buf_alloc(&preamble, raster_size);
	if(font->font_type == SUBTFM){
		*preamble->raster = 0;
		goto c_inf;
	}
	if(font->n[MAX_NAME_LEN-1] == '!'){
		memset(preamble->raster, 0, raster_size);
		goto c_inf;
	}else if(font->n[MAX_NAME_LEN-1] == '#'){
		memset(preamble->raster, 0xff, raster_size);
		goto c_inf;
	}
	switch (font->font_type) {
	  case (PKD_FONT):
	  case (PK_FONT):
dec_pk:	  decode_pk(pk, preamble, flag_byte, font);
		  /*  pk-fontの展開 */
		  goto c_inf;
#ifdef	USE_WINFONT
	  case(WINTT_FONT):
winttf:
#ifdef	USE_SUBFONT
		  if (font->sfd_id >= 0)
			char_code = lookup_sfd_record(font->sfd_id, char_code);
#endif
		  GetWinjTTGlyph((V_JFM*)(font->vjfm), char_code,
			(font->size_para+sp_per_pxl/2)/sp_per_pxl,
			preamble, 2, font->n);
		  preamble->shift_up_ptex = preamble->shift_right_ptex = 0;
		  goto c_inf;
#endif
	  case (PXL1001):
		  exp_1001(pk, preamble, font);
		  goto c_inf;
	  case (PXL1002):
		  exp_1002(pk, preamble, font);
		  goto c_inf;
	  case (PXL1003):
		  exp_1003(pk, preamble, font);
		  goto c_inf;
	  case (JXL):
		  decode_jxl(pk, preamble, flag_byte, font);
		  goto c_inf;
#ifdef VFD
	  case (VFD_FONT):
		  decode_vfn(new_code, pk, preamble, font);
		  goto c_inf;
#endif
#ifdef TTFONT
#ifdef USE_ETF
	  case (ETF_FONT):
		 switch(font->etf_type){
			case PK_FONT:
				goto dec_pk;
			case VIRTUAL_FONT:
				memcpy(preamble->raster, pk, preamble->byte_width);
				goto c1_inf;
			case TT_FONT:
				get_ettfont(new_code, preamble, font);
				break;
			case WINTT_FONT:
				goto winttf;
			default:
				goto cmttf;
		}
		break;
#endif
cmttf:
	  case (CMTTF):
		  get_cmttfont(new_code, preamble, font);
		  break;
#endif
	  case (ROM_FONT):
		  error(PROGRAM_STOP, "NO ROM FONT");
		  break;
#ifndef	NOVFONT
	  case (ZS_FONT):
#ifdef BEZIERFONT
	  case (JG_FONT):
#endif
#ifdef TTFONT
	  case (TT_FONT):
#endif
#ifdef	USE_WINFONT
	  case (WINJTT_FONT):
#endif
		  get_vfont(new_code, preamble, font);
#ifdef	USE_WINFONT
		  if(font->font_type != WINJTT_FONT)
				break;
#ifdef	WIN32G
		  if(f_propw){
			V_JFM *vjfm;
			static V_JFM *vjfmo;

			if(f_propw > 0x220 || (f_propw++ > 1 && new_code == 0x3D2A)){
				vjfmo = NULL;
				SetPropw(0);
			}else{
				if(f_propw == 2){
					vjfm = get_vjfm((font->ext.kdir)->fh);
					if(vjfmo != vjfm){
						error(C_MSG, "#Font: \"%s\"\n",
							(vjfm==v_tfm)?check_ftt(font->n)
							:(vfont[vjfm->font_no]->v_font_name + 1));
						vjfmo = vjfm;
					}
				}
				error(C_MSG, "%03d %c%c %X\n", font->f_goth & F_TATE?
					(-preamble->shift_up_ptex):preamble->shift_right_ptex, 
					jistojms(new_code) >> 8, jistojms(new_code) & 0xff, new_code);
			}
		  }
#endif
		  if(font->f_goth & F_TATE){
				tmp = -preamble->shift_up_ptex ;
				win_off =  -preamble->depth_offset;
				preamble->depth_offset = preamble->width
										- preamble->pitch_offset
										- font->ext.kdir->width*3/8;
// error(C_MSG, "%d %d %d %d %d\n",preamble->depth_offset, preamble->width, font->ext.kdir->width, preamble->pitch_offset, win_off);
		  }else{
				tmp = preamble->shift_right_ptex;
				win_off = -preamble->pitch_offset;
		  }
		  if(!f_kglue){
			tmp -= sptopixel(preamble->tfm_width);
			preamble->shift_up_ptex = preamble->shift_right_ptex = 0;
			if (new_code <= 0x2125	/* 、。，．゛゜°′″*/
			  || (new_code <= 0x212c && new_code >= 0x212b)
			  || (new_code >= 0x216b && new_code <= 0x216d)) {
				tmp = 0;
			}
			else if (new_code <= 0x215b && new_code >= 0x2146) {
				if (new_code & 1)
					tmp = 0;		/* カッコ閉じ */
			}
			else
				tmp /= 2;
		  }else{
			jtfm = jfm_read(font, new_code);
			tmp = sptopixel(mult20(jtfm->glue+jtfm->plus, font->size_para));
		  }

		  preamble->pitch_offset = tmp - win_off - font->ext.kdir->size;
		  preamble->depth_offset += font->ext.kdir->base
									- font->ext.kdir->height;
#endif
		  break;
#endif
	  case (JIS_FONT):
		  get_kfont(new_code, preamble, font);
		  break;
	  case (JIS_PK):
	  case (JIS_PKH):
	  case (GAIJI):
		  get_knjpk(new_code, preamble, font);
		  break;
	}
	if (font->f_goth & K_DBL)
		font_dbl(preamble);
c_inf:
	if (f_modify){
		if (f_modify & f_ROTATE)
			rotate_getfont(preamble);
		if (f_modify & (f_KSIZE|f_SIZE))
			resize_getfont(preamble, new_width, new_height);
	}
c1_inf:
	new_info = expand_char_info_list();
	/*  char_info-listに加える．*/
	new_info->code = char_code;
	new_info->next_char = new_info->former_char = NULL;
	if (flag_nf == 0 || n_flush != raster_buf_pointer->flush)
		font->char_info[char_code & (CHAR_ROOT - 1)] = new_info;
	else if (flag_nf > 0)
		char_info->next_char = new_info;
	else
		char_info->former_char = new_info;
	RETURN(preamble);
}

static void font_dbl(PREAMBLE *preamble)
{
	uchar far *top;
	uint ch1, ch2;
	int lin, col, width;
	int off1, off2, i;

	width = (preamble->byte_width + 1) / 2;
	top = preamble->raster;
	off1 = ((preamble->height) / 2 - 1) * width;
	off2 = (preamble->height - 2) * preamble->byte_width;
	for (lin = (preamble->height) / 2 - 1; lin >= 0; lin--) {
		for (col = preamble->byte_width - 1; col >= 0; col--) {
			ch1 = top[off1 + col / 2];
			ch2 = 0;
			if (col & 1) {
				for (i = 1; i < 16; i += i) {
					ch2 >>= 2;
					if (ch1 & i)
						ch2 |= 0xc0;
				}
			}
			else {
				for (i = 16; i < 256; i += i) {
					ch2 >>= 2;
					if (ch1 & i)
						ch2 |= 0xc0;
				}
			}
			top[off2 + col] = top[off2 + preamble->byte_width + col] = ch2;
		}
		off1 -= width;
		off2 -= preamble->byte_width * 2;
	}
}

static void exp_1001(BUFFER *pk, PREAMBLE *preamble, FONT_INFO *font)
{
	int i, j, k;
	BUFFER *dest;
	BUFFER *pkt;

	k = ((preamble->byte_width + 3) / 4) * 4;
	pk = font->pk + (uint)get_long(pk) * 4;
	dest = preamble->raster;
	for (i = preamble->height; i > 0; i--) {
		pkt = pk;
		for (j = preamble->byte_width; j > 0; j--) {
			*dest++ = *pkt++;
		}
		pk += k;
	}
}

static void exp_1002(BUFFER *pk, PREAMBLE *preamble, FONT_INFO *font)
{
	pk = font->pk + (uint)get_long(pk);
	memcpy(preamble->raster, pk, preamble->byte_width * preamble->height);
}

static void exp_1003(BUFFER *pk, PREAMBLE *preamble, FONT_INFO *font)
{
	BUFFER *pkt;
	uchar flag;

	flag = *(pkt = font->pk + (uint)get_long(pk));
	if (flag & 64) {
		memcpy(preamble->raster, pkt+1, 
			preamble->byte_width * preamble->height);
	}
	else {
		flag = ((flag << 4) & 0xff) + ((flag & 128) >> 4);
		decode_pk(pkt + 1, preamble, flag, font);
	}
}

static void rotate_getfont(PREAMBLE *preamble)
{
	BUFFER *buf;
	BUFFER *src_buf;
	int new_width, new_height, new_byte_width;
	long size;

	new_byte_width = ((new_width = preamble->height)+7)/8;
	new_height = preamble->width;
	size = (long)new_byte_width * new_height;
	src_buf = preamble->raster;

	buf = rotate_raster(preamble);
	memcpy(src_buf, buf, size);
	if(buf != &common_work[0])
		Free(buf);
	preamble->width  = new_width;
	preamble->height = new_height;
	preamble->byte_width = new_width;
}

static void resize_getfont(PREAMBLE *preamble, int width, int height)
{
	int src_width, src_height;
	uint size, new_size;
	uchar *src_buf;

	src_width = preamble->width;
	size = ((long)(src_width + 7)/8)*(src_height = preamble->height);
	if ((src_buf = (size <= COMMON_SIZE)?tmp_buf:get_near_work(size)) == NULL){
		error(WARNING, "No memory to resize font");
		return;
	}
	memcpy(src_buf, preamble->raster, size);
	preamble->height = height;
	new_size = (preamble->byte_width = ((preamble->width = width) + 7)/8)
				* height;
	resizefont(src_buf, src_width, src_height, preamble);
	if (new_size < size) cut_raster(size - new_size);
}

static void get_kfont(int char_code, PREAMBLE *preamble, FONT_INFO *font)
{
	int sc;
	KFONT *kf;

	kf = font->ext.kdir;
	sc = (((uint)char_code >> 8) - 0x21) * 94;
	sc += ((char_code & 0xff) - 0x21);
	lseek(kf->fh, (long)sc * (long)(kf->size), SEEK_SET);
	file_read(kf->fh, preamble->raster, kf->size);
}

static void get_knjpk(int char_code, PREAMBLE *preamble, FONT_INFO *font)
{
	int sc;
	int pktype;
	int total;
	int *tbl;
	uint size;
	long seek_pt;
	long lsize;
	uchar temp[10];
	KFONT *kf;

	kf = font->ext.kdir;
	size = kf->size;
	lsize = kf->height*(long)((kf->width+7)/8);

	switch(font->font_type){
		case JIS_PK:
			pktype = 3;
			break;

		case JIS_PKH:
			pktype = 5;
			break;

		case GAIJI:
#ifdef JGAIJI
			if (f_gaiji) return;
#endif
			pktype = 0;
			lseek(kf->fh, 32, SEEK_SET);
			for (sc = total = 0; sc <= total; sc++){
				if (!(sc & 0xff)){
					read(kf->fh, common_work, 0x200);
					tbl = (int*) common_work;
					if (!sc){
						total = *tbl++;
						continue;
					}
				}
				if (*tbl++ != char_code) continue;
				seek_pt = lsize*(sc - 1) + total*2 + 34;
				goto cpy;
			}
			error(FONT_MISMATCH, "%5d: %s %s->%s(%XH)",
				  font->font_code, font->n, get_font_name(font),
				  font->ext.kdir->name, char_code);
	}
	sc = (((uint)char_code >> 8) - 0x21) * 94;
	sc += ((char_code & 0xff) - 0x21);
	lseek(kf->fh, (long)sc * pktype + 32, SEEK_SET);
	read(kf->fh, temp, 10);
	if (pktype == 3){
		seek_pt = (((long)(temp[0] & 0x3f)) << 16);
		seek_pt += (((long)(temp[1])) << 8) + temp[2];
	}else{
		seek_pt = long_int(temp+1);
		size = long_int(temp+6) - seek_pt;
	}
cpy:
	lseek(kf->fh, seek_pt, SEEK_SET);
	if ( (pktype == 3 && (temp[0] & 0x80) != 0)
	 ||  (pktype == 5 && (temp[0] & 0x0f) == 0x0f)
	 ||   pktype == 0 ){
		file_read(kf->fh, preamble->raster, size);
	}
	else{
		ask_pk_buf(lsize + 4);
		if (size) file_read(kf->fh, pk_buf_pointer->current, size);
		if (pktype == 3)
			decode_pk(pk_buf_pointer->current, preamble,
				(12 << 4) + ((temp[0] & 0x40) >> 3), font);
		else{
			save_long(pk_buf_pointer->current + size, 0x0f0f0000L);
			decode_jxl(pk_buf_pointer->current, preamble, temp[0], font);
		}
	}
}

static BUFFER *get_pk(int char_code, FONT_INFO *font, int *flag_ptr)
	/*  char_codeのpk-fontを得る．pk-fontがloadされていないときは，
	 *  loadする．pk-fontはシーケンシャルなので，char_codeの部分を
	 *  サーチして，そのpointerを返す．
	 */
{
	int flag_byte, tmp, width, total, i, pos, kk_scale;
	long base_ratio;	/* JFMより選られるベースラインの高さ */
	JFM_DATA *jtfm;
	long packet_length, id;
	SCALED_PT ptwork;

	/*  intで充分なのだが，一応longにしておく．*/
	BUFFER *pk;
	BUFFER *pk0;
	KFONT *kf;
	long far *jxl_info;
	uchar f_head[35];
	char *msg;

	ENTER("get_pk");
	f_get_pk++;

	if (!font->pk) {
		/*  pk-font, tfm/jfm/vf がメモリー上に無かったら... */
		font->pk = load_pk(font->name, font->n);
		if(font->font_type == SUBJFM){
jtfm:		if(char_code < 0x2121)
				char_code = 0x2421;
			pk = font->pk;
			goto jfmpos;
		}
		if(font->font_type == SUBTFM){
			if(   font->pk[0] == 0
			  && (font->pk[1] == 2 || font->pk[1] == 8) ){
				font->font_type = SUBJFM;
				goto jtfm;
			}
			return NULL;
		}
resol:	tmp = font->pk[0] + ((int)((uchar)(font->pk[1])) << 8);
#ifdef	USE_WINFONT
		pos = strlen(font->name) - 4;
		if(  pos > 0
		  && !strcmp(font->name + pos, ".tfm")
		  && tmp != JTFMP_ID
		  && tmp != JTFM_ID
		  && (pk0 = (BUFFER *)check_wintt(font->n)) != NULL){ /* WINTT_FONT */
#ifdef	USE_SUBFONT
			font->sfd_id = current_sfd_id;
			current_sfd_id = -1;
#endif
			font->font_type = WINTT_FONT;
			font->vjfm = pk0;
			ResetWinTTCache();
			pk = font->pk + 24;
			goto checksum;
		}
#endif
		switch(tmp){
		  case (0):
			  (HUGE_BUF *)pk =
				  (HUGE_BUF *)(pk_buf_pointer->current) - 6;
			  pos = get_int(pk);
			  tmp = font->pk[2] + ((int)((uchar)(font->pk[3])) << 8);
			  if (tmp == PXL1001_ID) {
				  font->font_type = PXL1001;
				  font->ext.dir = font->pk + pos * 4;
			  }
			  else {
				  if (tmp == PXL1002_ID) {
					  font->font_type = PXL1002;
					  font->ext.dir = font->pk + pos;
				  }
				  else {
					  if (tmp == PXL1003_ID) {
						  font->font_type = PXL1003;
						  font->ext.dir = font->pk + pos;
					  }
					  else
						  goto err_id;
				  }
			  }
			  (HUGE_BUF *)pk =
				  (HUGE_BUF *)(pk_buf_pointer->current) - 20;
			  goto checksum;

		  case (JXL4_0_ID):
			  if (font->pk[2] + ((int)((uchar)(font->pk[3])) << 8)
				  != JXL4_1_ID)
				  goto err_id;
			  pk = font->pk + 4;
			  font->font_type = JXL;
			  goto checksum;

		  case (JTFMP_ID):
			  font->f_goth |= F_TATE;
		  case (JTFM_ID):
			  if (font->font_type != UNKNOWN)
				  break;
			  /* jtfm = jfm_read( font, char_code );*/
			  /* jtfm = jfm_read(font, 0x3021); */
			  jtfm = jfm_read(font, 0);
			  /*精度を落とさないように割り算. 0〜1000に変更*/
			  base_ratio = (jtfm->depth) /
				  ((id = jtfm->depth + jtfm->height) >> 10);
			  base_ratio = (base_ratio * 1000L) >> 10;
			  kk_scale = k_scale*952/1000;
			  ptwork = mult20(id, font->size_para / 250 * kk_scale /4);
			  font->k_height = (font->f_goth & F_TATE)?
						sptopixel(ptwork) : vtopixel(ptwork);
			  width = sptopixel(mult20((id = jtfm->width),
									   font->size_para));

			  ptwork = mult20(id, font->size_para / 250 * kk_scale);
			  font->k_width = (font->f_goth & F_TATE)?
						vtopixel(ptwork/4) : sptopixel(ptwork/4);
			  tmp = 0;
			  if(font->k_width < 3000){
				  if(( (font->f_goth & F_TATE)? 
					vtopixel(ptwork) : sptopixel(ptwork) ) % 4 < 2)
				  tmp = 1;
			  };
			  if (kk_scale > 1000)
				  width = font->k_width;
			  kf = open_kfont(font, width, tmp, jtfm);
			  /* ↓bitmap font だった場合．．． */
			  if (font->font_type != ZS_FONT
#ifdef BEZIERFONT
				&& font->font_type != JG_FONT
#endif
#ifdef TTFONT
				&& font->font_type != TT_FONT
#endif
#ifdef	USE_WINFONT
				&& font->font_type != WINJTT_FONT
#endif
#ifdef LBP
				&& font->font_type != JLBP
#endif
				) {
				  lseek(kf->fh, 0L, SEEK_SET);
				  read(kf->fh, f_head, 35);
				  if (f_head[0] == 0 && f_head[1] == 0 && f_head[2] == PK_PRE){
					switch(f_head[3]){
						case 'K':
							tmp = 3;
							font->font_type = JIS_PK;
							break;

						case 'H':
							tmp = 5;
							font->font_type = JIS_PKH;
							break;

						case 'G':
							tmp = 0;
							font->font_type = GAIJI;
							break;

						default:
							goto jis_font;
					}
					kf->width = f_head[4] + ((uint)(f_head[5]) << 8);
					kf->height = f_head[6] + ((uint)(f_head[7]) << 8);
					kf->size = (kf->width + 7) / 8 * kf->height;
					font->last = (!tmp)? 0x7fff:
						(((uint)f_head[33] << 8) + (uint)f_head[34] - 32)/tmp;
					if (tmp == 5) font->last--;
#ifdef	DBGPO
	printf("PK/JIS:%d, w %d, h %d, s %d, l %d\n", 
	tmp, kf->width, kf->height, kf->size, font->last);
#endif
				  }
				  else {
jis_font:			  font->font_type = JIS_FONT;
					  font->last
						  = (int)(filelength(kf->fh) / kf->size);
				  }
				  font->last =
					  (((uint)font->last / 94) << 8)
					  + (font->last % 94) + 0x2120;
				  if (font->last < 0)
					  font->last = 0x7fff;
			  }
			  else {
				  /* (擬似)スケーラブルフォントの場合 */
					font->last = 0xffff;
			  }
#ifdef	USE_WINFONT
			/* 9.62216/(7.77588+1.38855) = 9.62216/9.16433 = 1.049946 */
			/* 10.0/9.16433 = 1.091187 */
			  if(font->font_type == WINJTT_FONT){
					ptwork = mult20(jtfm->width, 
						font->size_para/250*k_scale/4);
					if(font->f_goth & F_TATE){
						font->k_height = sptopixel(ptwork);
						kf->base = 0;
					}else{
						font->k_height = vtopixel(ptwork);
						kf->base = font->k_height
							*(((f_ktbase)?(BASE_RATIO - base_ratio):0)
							- k_base)/1050;
					}
			  }else
#endif
			  {
				if (font->f_goth & (K_SCALE|K_SCALE2))
						tmp = font->k_height;
				else	tmp = (font->f_goth & F_TATE)?kf->width:kf->height;

				kf->base = (int)(((1000L - base_ratio
					- ((font->f_goth & F_TATE)? 0 : k_base))
					* (unsigned long) tmp + 500) / 1000L);
			  }
#ifdef LBP
			  if (font->font_type != JLBP)
#endif
			  {
				  font->ext.kdir = kf;
				  if (strstr(kf->name, goth) != NULL)
					  goto checkj;
#ifndef NOVFONT
				  if (font->font_type == ZS_FONT
#ifdef BEZIERFONT
					  || font->font_type == JG_FONT
#endif
#ifdef TTFONT
					  || font->font_type == TT_FONT
#endif
					  ) {
					  switch (chk_vfont_goth(font)) {
						case 1:
							g_font = 0;
							break;
						case 2:
							(font->f_goth) |= (g_font = 1);
							break;
						default:
							(font->f_goth) |= (g_font = chk_goth(font));
					  }
				  }
				  else
					  (font->f_goth) |= (g_font = chk_goth(font));
#else
				  (font->f_goth) |= (g_font = chk_goth(font));
#endif
			  }
checkj:		  pk = font->pk + 28;
			  goto checksum;

		  case (PKDW_ID):
			  font->font_type = PKD_FONT;
			  goto check0;

		  case (PKW_ID):
			  font->font_type = PK_FONT;
check0:		  pk = font->pk;
			  pk += *((uchar far *)(pk + 2)) + 7;
checksum:	  if (f_font_c && (id = get_long(pk)) != 0
				  && font->c != 0 && font->c != id)
				  error(WARNING,
						"check sum doesn't match in Font%3d: "
						"dvi(%08lX) %s(%08lX)",
						font->font_code, font->c,
						(font->font_type >= ROM_FONT) ? "jfm" : "font", id);
			  break;
#ifdef VFD
		  case (VFDW_ID):
			  font->font_type = VFD_FONT;
			  pk = font->pk;
			  pk += *((uchar far *)(pk + 2)) + 7;
			  break;
#endif
#ifdef TTFONT
		  case (CMTTF_ID):
			  font->font_type = CMTTF;
			  if (font->ext.fh <= 0)
				  font->ext.fh = openf(font->name, O_RDONLY | O_BINARY);
			  if (((CMTT_INFO far *)(font->pk + 4))->f_have_tfm == TRUE) {
				  pk = font->pk + sizeof(CMTT_INFO) + 28;
				  goto checksum;
			  }
			  break;
#endif
#ifdef	VIRTUALFONT
		  case (VIRTUALFONT_ID):
			  font->font_type = VIRTUAL_FONT;
			  pk = font->pk + 2;
			  tmp = get_ubyte(pk);
			  move_ptr(pk, tmp);
			  goto checksum;
#endif

		default:				/* */
err_id:		  pos = strlen(msg = get_font_name(font));
			  i = 8;
			  if( pos > 13  && strcmpi(msg + pos - 4, ".tfm") == 0){
				while(i++ < 14){
					if(msg[pos-i] == ' '  ||
					   msg[pos-i] == '\\' || msg[pos-i] == '/'){
						if(tolower(msg[pos-i+1]) == 'c'
						&& tolower(msg[pos-i+2]) == 'm')
							i = 0;
						break;
					}
				}
			  }
			  error(UNPACK_ERROR, 
				"Illegal font ID: %s -> %s(%04X)\nCheck TEXPK!%s",
				font->n, msg, tmp, 
				(i)?"":" tfm file of CM font cannot be indicated.");
		}
#ifndef NO_NTTRPL
		if (font->code_offset >= 0) unify_nttjfont(font);
#endif
	}
#ifdef	USE_ETF
	if(font->font_type == UNKNOWN)
		goto resol;
#endif
	pk = font->pk;
#ifdef	USE_ETF
	if(font->font_type == ETF_FONT)
		return pk;
#endif
	if (font->font_type >= SUBJFM) {
		if ((char_code < 0x2121 || char_code > font->last)
		  && font->font_type != SUBJFM
		  && font->font_type != VIRTUAL_FONT
		  && font->font_type != WINJTT_FONT){
no_font:
			error(FONT_MISMATCH, "%5d: %s->%s %s(illegal char_code %XH)",
				  font->font_code, font->n, get_font_name(font),
				(font->font_type >= JIS_FONT) ? (font->ext.kdir)->name : "",
				  char_code);
		}
jfmpos:	
		move_ptr(pk, 2);
		total = get_int(pk);	/* nt */
		move_ptr(pk, 2);
		tmp = get_int(pk);		/* lh */
		move_ptr(pk, (tmp + 5) << 2);
		pk0 = pk;
		while (total-- > 0) {
			if (char_code == get_int(pk))
				RETURN(pk);
			move_ptr(pk, 2);
		}
		if (font->font_type >= JIS_FONT && font->ext.kdir->fh < 0)
			re_openf(font);
		RETURN(pk0 + 2);
	}
#if DEBUG & MEM_CHK
	_ptrchk = _pkptrchk;		/* memory check用 */
#endif
	if (f_resize && enlarge && font->font_type <= JXL)
		font->f_goth |= K_SCALE;
	switch (font->font_type) {

	  case (PK_FONT):
		  move_ptr(pk, 2);
		  tmp = get_ubyte(pk);
		  move_ptr(pk, tmp + 16);
		  /* Skip specials, design size, check sum,
			* hppp and vppp（とりあえずは，必要無いのでとばす．）
			*/
		  for (;;) {
			  if ((flag_byte = read_flag_byte(&pk)) == PK_POST)
				  goto no_font;
			  if (flag_byte < 0)
				error(FILE_FAULT, "Unexpected code %d in a PK font!\n%s", 
					-flag_byte, get_font_name(font));
			  switch (flag_byte & 7) {
				case 7:
					/* long-preamble */
					packet_length = get_long(pk);
					if (char_code == get_long(pk))
						goto pkfind;
					break;
				case 4:
				case 5:
				case 6:
					/* ex-short-preamble */
					packet_length =	( ( flag_byte & 3 ) << 16 ) + get_int(pk);
					goto chk;
				default:
					/* short preamble */
					packet_length = ((flag_byte & 7) << 8) +
						get_ubyte(pk);
chk:					if (char_code == get_ubyte(pk)) {
pkfind:						*flag_ptr = flag_byte;
#ifdef	USE_ETF
							if(f_make_pketf)
								SetETFindex(font, char_code, flag_byte,
								pk - font->pk, packet_length, 5);
#endif
						RETURN(pk);
					}
					break;
			  }
			  move_ptr(pk, (int)packet_length);
		  }

	  case (PXL1001):
	  case (PXL1002):
	  case (PXL1003):
		  RETURN(font->ext.dir + (char_code << 4));

	  case (PKD_FONT):
		  if (font->ext.fh <= 0)
			  open_pk(font);
		  if ((tmp = char_code - *(font->pk + 4)) < 0
			  || char_code > *(font->pk + 6))
			  goto no_font;
		  pk = font->pk + (font->k_width + 3 * tmp);
		  if ((packet_length = get_mid(pk)) == 0L)
			  goto no_font;
		  RETURN(get_pkd(font, packet_length, flag_ptr));

#ifdef VFD
	  case (VFD_FONT):
		  if (font->ext.fh <= 0)
			  open_vf(font);
		  if ((tmp = char_code - *(font->pk + 4)) < 0
			  || char_code > *(font->pk + 6))
			  goto no_font;
		  pk = font->pk + (font->k_width + 5 * tmp);
		  if ((packet_length = get_mid(pk)) == 0L)
			  goto no_font;
		  if ((width = get_int(pk)) == 0)
			  goto no_font;
		  RETURN(get_vfd(font, packet_length, (width * 20 + 15) / 16 * 2));
#endif

	  case (JXL):
		  if (font->ext.fh <= 0)
			  open_jxl(font);
		  jxl_info = (long far *)(font->pk);
		  if (char_code < 0x3021) {
			  if (jxl_info[i = 13] == jxl_info[14])
				  goto no_font;
			  tmp = 0x21;
		  }
		  else if (char_code < 0x5021) {
			  if (jxl_info[i = 14] == 0)
				  goto no_font;
			  tmp = 0x30;
		  }
		  else {
			  if (jxl_info[i = 15] == 0)
				  goto no_font;
			  tmp = 0x50;
		  }
		  pos = ((char_code >> 8) - tmp) * 94 + (char_code & 0x7f) - 0x21;
		  RETURN(get_jxl(jxl_info, font, jxl_info[i] + (pos << 3), flag_ptr));
#ifdef	VIRTUALFONT
	 case (VIRTUAL_FONT):
		  RETURN(get_virtualfont(font, char_code, flag_ptr));
#endif
	}
	RETURN(NULL);
}

static BUFFER *get_jxl(long far * jxl_info, FONT_INFO *font, long pos, int *flag_ptr)
{
	int flag_s, fd;
	uchar tmp[8], tmp0[2];
	long pos_x, pos_y, pos_tfm, pos_raster, packet_length;
	BUFFER *pk;

	lseek(fd = font->ext.fh, pos, SEEK_SET);
	read(fd, &(tmp[0]), 8);

	pos_tfm = jxl_info[6] + ((uint)tmp[0] << 2);
	pos_x = jxl_info[8] + (((uint)tmp[4] << 8) + (uint)tmp[5]) * 6L;
	pos_y = jxl_info[10] + (((uint)tmp[6] << 8) + (uint)tmp[7]) * 6L;
	pos_raster = (((long)(tmp[1])) << 16) + (((long)(tmp[2])) << 8) + tmp[3];

	lseek(fd, pos_raster, SEEK_SET);
	read(fd, &(tmp[0]), 1);
	flag_s = ((*flag_ptr = tmp[0]) & 0x30) >> 4;
	if ((*flag_ptr & 0x0f) == 14) {
		lseek(fd, pos_x + 2, SEEK_SET);
		read(fd, &(tmp0[0]), 2);
		packet_length = (tmp0[0] << 8) + tmp0[1];
		lseek(fd, pos_y + 2, SEEK_SET);
		read(fd, &(tmp0[0]), 2);
		packet_length *= (tmp0[0] << 8) + tmp0[1];
		packet_length = (packet_length + 7) >> 3;
		lseek(fd, pos_raster + 1, SEEK_SET);
	}
	else {
		packet_length = 0;
		while (flag_s-- >= 0) {
			read(fd, &(tmp[0]), 1);
			packet_length = (packet_length << 8) + tmp[0];
		}
	}
	if (ask_pk_buf(packet_length) == FAILURE)
		error(UNPACK_ERROR,
			  "Too big raster in %s", get_font_name(font));
	file_read(fd, (pk = pk_buf_pointer->current) + 12, (int)packet_length);
	pk[(int)packet_length + 12] = 0;
	pk[(int)packet_length + 13] = 0;
	pk[(int)packet_length + 14] = 0x0f;
	pk[(int)packet_length + 15] = 0x0f;
	lseek(fd, pos_x, SEEK_SET);
	file_read(fd, pk, 4);
	lseek(fd, pos_y, SEEK_SET);
	file_read(fd, pk + 4, 4);
	lseek(fd, pos_tfm, SEEK_SET);
	file_read(fd, pk + 8, 4);

	return (pk);
}

BUFFER *get_pkd(FONT_INFO *font, long pos, int *flag_ptr)
{
	long packet_length;
	int fd, k;
	uchar tmpc;

	union NUM {
		long l;
		uint i;
		uchar ch[4];
	}
	num;

	lseek(fd = font->ext.fh, pos, SEEK_SET);
	read(fd, &tmpc, 1);
	*flag_ptr = tmpc;
	if ((tmpc &= 7) == 7)
		k = 3;
	else {
		if (tmpc > 3)
			k = 1;
		else
			k = 0;
	}
	while (k >= 0)
		read(fd, &(num.ch[k--]), 1);

	switch (tmpc) {

	  case 7:
		  packet_length = num.ch[0] + (num.ch[1] << 8)
			+ (num.ch[2] << 16) + (num.ch[3] << 24);
		  read(fd, &num.l, 3);
		  break;

	  case 4:
	  case 6:
	  case 5:
		  packet_length = ((ulong)(tmpc & 3) << 16)
						 + num.ch[0] + (num.ch[1] << 8);
		  break;

	  default:
		  packet_length = (tmpc << 8) + num.ch[0];
		  break;
	}
	read(fd, &num.l, 1);
	if (ask_pk_buf(packet_length) == FAILURE)
		error(UNPACK_ERROR, "Too big raster in %s", font->pk + 5);
	file_read(fd, pk_buf_pointer->current, (int)packet_length);
	return (pk_buf_pointer->current);
}

#ifdef VFD
BUFFER *get_vfd(FONT_INFO *font, long pos, int packet_length)
{
	int fd;

	lseek(fd = font->ext.fh, pos, SEEK_SET);

	if (ask_pk_buf(packet_length) == FAILURE)
		error(UNPACK_ERROR, "Too big vector in %s", font->pk + 5);
	file_read(fd, pk_buf_pointer->current, packet_length);
	return (pk_buf_pointer->current);
}

#endif

static int read_flag_byte(BUFFER **pk_ptr)
	/*  flag byte を読み出す．specialsのときはスキップする．
	 */
{
	int flag_byte;
	BUFFER *pk;
	long tmp;

	ENTER("read_flag_byte");

	pk = *pk_ptr;
	flag_byte = get_ubyte(pk);
	while (flag_byte >= 240 && flag_byte != PK_POST) {
		/* Skip Specials
		 */
		switch (flag_byte) {
		  case 240:
		  case 241:
		  case 242:
		  case 243:
			  for (tmp = 0; flag_byte >= 240; flag_byte--)
				  tmp = (tmp << 8) + get_ubyte(pk);

			  move_ptr(pk, (uint)tmp);
			  break;
		  case 244:
			  move_ptr(pk, 4);
			  break;
		  case 245:
		  case 246:
			  break;
		  default:
			  flag_byte = -flag_byte;
			  goto quit;
		}
		flag_byte = get_ubyte(pk);
	};
quit:
	*pk_ptr = pk;
	RETURN(flag_byte);
}

static PREAMBLE *set_preamble(BUFFER **pk_ptr, int *ptr_flag_byte,
							  FONT_INFO *font, int char_code)
	/*  PREAMBLEを_raster_buf上に設定する．
	 */
{
	PREAMBLE *preamble;
	BUFFER *pk;
#ifdef	VFD
	BUFFER *font_pk;
#endif
	int tmp, tmph, tmpw, fsc, tw;

	ENTER("set_preamble");

	preamble = alloc_preamble();
	pk = *pk_ptr;
	fsc = 0;

	switch (font->font_type) {

	  case (SUBTFM):
		if(char_code >= 0x100)
			char_code = 'o';
		tmp = tfm_width(font->pk, char_code);
def:	preamble->tfm_width = mult20(tmp, font->size_para);
		preamble->width = preamble->height = preamble->pitch_offset
						= preamble->depth_offset = 1;
		break;

	  case (SUBJFM):
		tmp = jtfm_width(font, get_int(pk));
		goto def;

#ifdef	USE_WINFONT
	  case (WINJTT_FONT):
		preamble->tfm_width =
			mult20(jtfm_width(font, get_int(pk)), font->size_para);
		set_wintt_preamble(char_code, preamble, font);
		break;
#endif
	  case (ZS_FONT):
#ifdef BEZIERFONT
	  case (JG_FONT):
#endif
#ifdef TTFONT
ttfont:
	  case (TT_FONT):
#endif
		fsc = 2;
	  case (ROM_FONT):
	  case (JIS_FONT):
	  case (JIS_PK):
	  case (JIS_PKH):
	  case (GAIJI):
	  case (JLBP):
		  /*preamble->pitch_offset = 0;*/
		  if ( font->f_goth & K_SCALE2 ){
			  tmpw = font->k_width;
			  tmph = font->k_height;
			  if ( font->f_goth & F_TATE ){
				tmp  = tmpw;
				tmpw = tmph;
				tmph = tmp;
			  }
			  fsc  = 2;
		  }
		  else{
			  tmpw = (font->ext.kdir)->width;
			  tmph = (font->ext.kdir)->height;
		  }
		  if ( font->f_goth & F_TATE ){
			  rewrite_preamble_ptex(preamble, char_code, NULL);
			  fsc |= (preamble->rotate_ptex & 1);
		  }
		  preamble->width = (fsc==3)?tmph:tmpw;
		  preamble->height = (fsc==3)?tmpw:tmph;
		  preamble->depth_offset = (font->ext.kdir)->base;
		  if (font->f_goth & K_DBL) {
			  preamble->width *= 2;
			  preamble->height *= 2;
			  preamble->depth_offset *= 2;
		  }
		  if(font->font_type != ETF_FONT){
#ifdef	USE_ETF
			preamble->tfm_width = 
				mult20(tw = jtfm_width(font, get_int(pk)), font->size_para);
			if(f_make_jttetf && font->font_type == TT_FONT)
				SetETFindex(NULL, 0, tw, 0, 0, 4);
#else
			preamble->tfm_width = 
				mult20(jtfm_width(font, get_int(pk)), font->size_para);
#endif
		  }
		  if (font->f_goth & K_SCALE)
			  tmp = font->k_width;
		  else
			  tmp = (font->f_goth & F_TATE)?tmph:tmpw;

		  if ((tmp = tmp - sptopixel(preamble->tfm_width)) == 0) {
			  preamble->pitch_offset = 0;
		  }
		  else {
			  if (char_code <= 0x2125	/* 、。，．゛゜°′″*/
				  || (char_code <= 0x212c && char_code >= 0x212b)
				  || (char_code >= 0x216b && char_code <= 0x216d)) {
				  tmp = 0;
			  }
			  else if (char_code <= 0x215b && char_code >= 0x2146) {
				  if (char_code & 1)
					  tmp = 0;	/* カッコ閉じ */
			  }
			  else
				  tmp /= 2;
			  preamble->pitch_offset = tmp;
		  }
		  break;

	  case (PK_FONT):
	  case (PKD_FONT):
do_pk:		switch (*ptr_flag_byte & 7) {

			case 7:
				/* long format */
				preamble->tfm_width = mult20(get_long(pk), font->size_para);
				move_ptr(pk, 8);
				/* Skip hor_esc */
				preamble->width = (int)get_long(pk);
				preamble->height = (int)get_long(pk);
				preamble->pitch_offset = (int)get_long(pk);
				preamble->depth_offset = (int)get_long(pk);
				break;

			case 4:
			case 5:
			case 6:
				/* ex-short format */
				preamble->tfm_width = mult20(get_mid(pk), font->size_para);
				move_ptr(pk, 2);
				/* Skip hor_esc */
				preamble->width = get_int(pk);
				preamble->height = get_int(pk);
				preamble->pitch_offset = get_int(pk);
				preamble->depth_offset = get_int(pk);
				break;

			default:
				/* short format */
				preamble->tfm_width = mult20(get_mid(pk), font->size_para);
				move_ptr(pk, 1);
				/* Skip hor_esc */
				preamble->width = (int)get_ubyte(pk);
				preamble->height = (int)get_ubyte(pk);
				preamble->pitch_offset = (int)get_byte(pk);
				preamble->depth_offset = (int)get_byte(pk);
				break;
		  }
		  break;

#ifdef	USE_WINFONT
	case(WINTT_FONT):
		preamble->tfm_width =
				mult20(tw = tfm_width(font->pk, char_code), font->size_para);
#ifdef	USE_ETF
		if(f_make_mapetf)
			SetETFindex(font, char_code, tw, 0, 0, 6);
#endif
wintt:
#ifdef	USE_SUBFONT
		if (font->sfd_id >= 0)
			char_code = lookup_sfd_record(font->sfd_id, char_code);
#endif
		GetWinjTTGlyph((V_JFM*)(font->vjfm), char_code,
			(font->size_para+sp_per_pxl/2)/sp_per_pxl,
			preamble, 1, font->n);
		break;
#endif


#ifdef VFD
	  case (VFD_FONT):
		  font_pk = font->pk + font->k_width - 4;
		  preamble->tfm_width = mult20(get_long(font_pk), font->size_para);
		  preamble->width = sptopixel(preamble->tfm_width);
		  preamble->height = vtopixel(preamble->tfm_width);
		  preamble->pitch_offset = 0;
		  preamble->depth_offset = preamble->height * 4 / 5;
		  /* this value is ad hoc */
		  break;
#endif

#ifdef TTFONT
	  case (CMTTF):
		  ttf_metrics(font, char_code, preamble);
		  break;
#endif

#ifdef	USE_ETF
	  case (ETF_FONT):
		 etf_metrics(&pk, font, char_code, preamble);
		 switch(font->etf_type){
			case PK_FONT:
				*ptr_flag_byte = get_byte(pk) & 0xff;
				goto do_pk;
			case TT_FONT:
				goto ttfont;
			case VIRTUAL_FONT:
				goto skp;
			case WINTT_FONT:
				goto wintt;
			default:
				break;
		 }
		 break;
#endif
	  case (JXL):
		  preamble->pitch_offset = get_int(pk);
		  preamble->width = get_int(pk);
		  preamble->depth_offset = get_int(pk);
		  preamble->height = get_int(pk);
#ifndef NO_NTTRPL
		  if (font->code_offset >= 0) {
			get_long(pk);
			preamble->tfm_width =
				mult20(nttf_width[font->pt_size], font->size_para);
			preamble->pitch_offset =
				(((font->f_goth & K_SCALE)?font->k_width:preamble->width)
					- sptopixel(preamble->tfm_width))/2;
		  }
		  else
#endif
		  preamble->tfm_width = mult20(get_long(pk), font->size_para);
		  break;

	  case (PXL1001):
	  case (PXL1002):
	  case (PXL1003):
		  preamble->width = get_int(pk);
		  preamble->height = get_int(pk);
		  preamble->pitch_offset = get_int(pk);
		  preamble->depth_offset = get_int(pk);
		  get_long(pk);
		  preamble->tfm_width = mult20(get_long(pk), font->size_para);
		  pk -= 8;
		  break;
#ifdef	VIRTUALFONT
	  case (VIRTUAL_FONT):
		  preamble->width = preamble->height = preamble->pitch_offset
						  = preamble->depth_offset = 1;
		  tmp = virtualfont_tfm_width(pk, *ptr_flag_byte, char_code);
		  preamble->tfm_width = mult20(tmp, font->size_para);
#ifdef	USE_ETF
		  if(f_make_vfetf)
			SetETFindex(NULL, 0, tmp, 0, 0, 4);
#endif
		  break;
#endif
	}
	preamble->byte_width = (preamble->width + 7) / 8;
skp:
	*pk_ptr = pk;

	if (!(fsc&1)){
		preamble->shift_up_ptex = preamble->shift_right_ptex = 0;
		preamble->rotate_ptex = 0;
	}

	RETURN(preamble);
}

static long jtfm_width(FONT_INFO *font, int c_type)
{
	BUFFER *pk;
	int tmp, tmp1;

	ENTER("jtfm_width");

#ifndef NO_NTTRPL
	if (font->code_offset >= 0)
		RETURN(nttf_width[font->pt_size]);
#endif
	pk = font->pk + 2;
	tmp = get_int(pk);			/* nt */
	move_ptr(pk, 2);			/* lf */
	tmp += get_int(pk);			/* lh */
	move_ptr(pk, 2);			/* bc = 0 */
	tmp1 = get_int(pk);			/* ec */
	move_ptr(pk, (tmp + 4 + c_type) << 2);
	tmp += (int)get_byte(pk);	/* width_index */
	pk = font->pk;
	move_ptr(pk, (tmp + tmp1 + 8) << 2);

	RETURN(get_long(pk));

}

/* buffer 上の tfm 情報から tfm_width を得る */
long tfm_width(BUFFER *tfm, int code)
{
	BUFFER *pk;
	int lh, bc, ec, index;

	ENTER("tfm_width");

	pk = tfm + 2;
	lh = get_int(pk);			/* lh */
	bc = get_int(pk);			/* bc */
	ec = get_int(pk);			/* ec */
	move_ptr(pk, (4 + lh + code - bc) << 2);
	index = (int)get_byte(pk);	/* width_index */
	pk = tfm;
	move_ptr(pk, (6 + lh + ec - bc + 1 + index) << 2);

	RETURN(get_long(pk));
}

JFM_DATA *jfm_read(FONT_INFO *font, int char_code)
	/* read JFM files properly   21 July 1992, by Naochan! */
	/* char_code = 0 means default (char_type = 0) */
{
	static JFM_DATA jtfm;

	BUFFER *pk;
	int i, c_type;
	int tmp, tmp_w, w_to_h, h_to_d, d_to_i, i_to_gk, tmp2, tmp3;
	int index_w, index_h, index_d, index_i, index_gk, get_byte_tmp;
	int lh, nt, ec, nw, nh, nd, ni, nl, nk, ng, np, tag;

	ENTER("jfm_read");

	pk = font->pk;
	tmp = get_int(pk);			/* id */
	jtfm.id = tmp;
	nt = get_int(pk);			/* nt */
	move_ptr(pk, 2);			/* skip lf  */
	lh = get_int(pk);			/* lh */
	move_ptr(pk, 2);			/* skip bc(=0) */
	ec = get_int(pk);			/* ec */
	nw = get_int(pk);			/* nw */
	nh = get_int(pk);			/* nh */
	nd = get_int(pk);			/* nd */

	ni = get_int(pk);			/* ni */
	nl = get_int(pk);			/* nl */
	nk = get_int(pk);			/* nk */
	ng = get_int(pk);			/* ng */
	np = get_int(pk);			/* np */

	move_ptr(pk, lh << 2);		/* set c_type */
	for (i = c_type = 0; i < nt; i++){
		tmp2 = get_uint(pk);
		tmp3 = get_uint(pk);
		tmp2 += (tmp3>>8)<<16;  /* support 24bit char_code */
		tmp3 &= 0xffL;
		if (char_code == tmp2){
			c_type = tmp3;
			move_ptr(pk, (nt - i - 1) << 2);
			break;
		}
	}
	jtfm.char_type = c_type;
	if(c_type != 0){
		(int)get_byte(pk);
		(int)get_byte(pk);
		tag = get_byte(pk);
		index_gk = (int)get_byte(pk);	/* glue/kern after c_type = 0 */
		move_ptr(pk, (c_type -1)<< 2);
	}
// error(14, "c_type %d:tag %d", c_type, tag & 3);
	index_w = (int)get_byte(pk);			/*  width_index */
	get_byte_tmp = (int)get_byte(pk);
	index_h = (get_byte_tmp & 0x00F0) >> 4;	/* height_index */
	index_d = get_byte_tmp & 0x000F;		/*  depth_index */
	index_i = ((int)get_byte(pk) & 0x00FC) >> 2; /* italic_index */
	get_byte(pk);							/* glue-kern_inex */

	tmp_w = (lh + nt + ec + index_w + 8) << 2;
	w_to_h = (nw - index_w + index_h - 1) << 2;
	h_to_d = (nh - index_h + index_d - 1) << 2;
	d_to_i = (nd - index_d + index_i - 1) << 2;

	pk = font->pk;				/* return to the home position */
	move_ptr(pk, tmp_w);
	jtfm.width = get_long(pk);
	move_ptr(pk, w_to_h);
	jtfm.height = get_long(pk);
	move_ptr(pk, h_to_d);
	jtfm.depth = get_long(pk);
	move_ptr(pk, d_to_i);
	jtfm.italic = get_long(pk);
	if(c_type != 0 && (tag & 1)){
		i_to_gk = (ni- index_i + index_gk- 1) << 2;
		move_ptr(pk, i_to_gk);
		tmp_w = 0;
		do{
			i = get_byte(pk);	
			tmp_w++;
			if(c_type == ( get_byte(pk))){		/* char_type 0 -> c_type */
				if(get_byte(pk) & 0x80)
					goto kern;
				move_ptr(pk, (nl+nk-index_i- tmp_w + 3*get_byte(pk))<<2);
				jtfm.glue  = get_long(pk);
				jtfm.plus  = get_long(pk);
				jtfm.minus = get_long(pk);
				goto ext;
			}else{
				get_byte(pk);
				get_byte(pk);
			}
		}while(!(i&0x80));
	}
kern:
	jtfm.glue = jtfm.plus = jtfm.minus = 0;
ext:
#ifndef NO_NTTRPL
	if (font->code_offset >= 0) {
		jtfm.width = nttf_width[font->pt_size];
		jtfm.height = nttf_height[font->pt_size];
		jtfm.depth = nttf_depth[font->pt_size];
	}
#endif
	RETURN(&jtfm);
}

#ifdef	USE_WINFONT
#if 0
BOOL IsAllTT(void)
{
	FONT_INFO *font;

	for (font = first_font_info; font; font=font->next_font){
		if(font->font_type == WINTT_FONT || font->font_type == WINJTT_FONT)
			continue;
		if(font->font_type == UNKNOWN &&
		  !strcmp(font->name + strlen(font->name) - 4, ".tfm"))
			continue;
		return FALSE;
	}
	return TRUE;
}
#endif
#endif

#if DEBUG & MEM_CHK
static void _pkptrchk(BUFFER *ptr)
{
	if ((uchar huge *)ptr < (uchar huge *)(pk_buf_pointer->start)
		|| (uchar huge *)ptr >= (uchar huge *)(pk_buf_pointer->end))
		error(MEMORY_FAULT, "pk-buffer");
}

#endif

#ifdef AX
int toSJISc(jis)	/* JIS->SJIS */
	unsigned short jis;
{
	register unsigned short h, l;

	h = (jis >> 8) & 0xff;
	l = jis & 0xff;
	if (h & 1)
		l += 0x1f;
	else
		l += 0x7d;
	if (l >= 0x7f)
		l++;
	h = (h - 0x21 >> 1) + 0x81;
	if (h > 0x9f)
		h += 0x40;
	RETURN(h << 8 | l);
}

#endif

#ifndef NO_NTTRPL
static void unify_nttjfont(FONT_INFO *font)
{
	FONT_INFO *dfont;
	for(dfont = first_font_info; dfont; dfont = dfont->next_font){
		if (dfont->font_type == ONDEMAND)
			resolve_font(dfont);
		if (dfont->code_offset >= 0
				&& dfont->family_code == font->family_code
				&& dfont->font_type == UNKNOWN) {
			dfont->font_type = font->font_type;
			dfont->f_goth = font->f_goth;
			dfont->pk = font->pk;
			dfont->k_width = font->k_width;
			dfont->k_height = font->k_height;
			dfont->last = font->last;
			dfont->ext = font->ext;
#ifdef	LBP
			dfont->lbp_font_inf = font->lbp_font_inf;
#endif
		}
	}
}
#endif

static void resizefont(uchar *raster, uint src_x_dots, uint src_y_dots,
	PREAMBLE *preamble)
/*
 *  ROM FONT の拡大・縮小
 *
 * ●用法
 *
 * raster に格納されている ROM フォントを拡大／縮小して
 * preamble->raster にコピ−。
 *
 * フォントのサイズが 64KByte 以内であれば、フォントの縦横のサイズに
 * 制限はない(はずである)。
 * 
 * ●アルゴリズム
 * 
 * コピー元のフォントの各ドットがコピー先のどのドットにあたるか計算し
 * ながら、コピーする。
 * 
 * 縮小する場合は、コピー元の複数ドットがコピー先の１ドットに対応する。
 *（Naochan!氏の minifont 関数のアルゴリズム）
 * 
 * 逆に、拡大する場合は、コピー元の１ドットをコピー先の複数ドットに対
 * 応させる必要がある。そのために、元の１ドットを (dx0,dy0)-(dx1,dy1)
 * の範囲ドットに対応させるようになっている。
 * （吉澤氏の residebf.c のアルゴリズム）
 * 
 * フォントが、かすれたり、逆に潰れたりしないように、(dx0,dy0)-(dx1,
 * dy1)が他のドットとちょうど重ならない範囲となるように、少し工夫して
 * いる。(縮小する場合はどうしても重なってしまうが、拡大する場合は、
 * 重ならないはずである。)
 * 
 * 途中、(long) にキャストしているのは、16bit int のオーバー・フロー
 * を避けるためである。src_[xy]_dots / 2 を加算しているのは、四捨五入
 * のためである。
 *
 * この関数は、特別な作業領域を必要としない。また、スタック上に大きな
 * 作業配列をとるようなこともしてない。
 *
 * 拡大時に、線の太さが一定になるように、拡大前の１ドットが拡大後の何
 * ドットにあたるのかをあらかじめ計算している。（thick_[xy]） その際、
 * 隣接するドットとの間に隙間ができないように補正している。
 * （松田氏のアルゴリズム）
 * 
 * 若干の高速化とバグ修正を行った（SHIMA）
 *
 * ※このサブルーチンは、Naochan!によって Ver.2.38 からサポートされた
 *   ROMfont縮小ルーチン minifont()と、吉澤氏が作成した resizebf.c を
 *   融合し、書き直したものです。
 *
 */

{
#define CHK_DOT(x, y) (raster[((uint)y)*src_x_bytes + (((uint)x)>>3)] & row[(x)&7])
#define SET_DOT(x, y) (dst[((uint)y)*dst_x_bytes + (((uint)x)>>3)] |= row[(x)&7])

	static uchar row[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
	BUFFER *dst;
	BUFFER *d;
	uint n;
	uint src_x_bytes;			/* x-方向のバイト数			*/
	uint dst_byte_size;			/* フォント全体のバイト数	*/
	int  sx, sy;				/* コピー元のドット位置		*/
	int  dx, dy;				/* コピー先のドット位置		*/
	uint dx0, dy0, dx1, dy1;	/* コピー先のドット範囲		*/
	uint dst_x_bytes;			/* コピー先のバイト幅		*/
	uint dx0_m, dy0_m, dx1_m, dy1_m, dx1_p;	/* 計算用		*/
	uint thick_x, thick_y;		/* 線の太さ					*/
	uint tx_half, ty_half;      /* (thick_[xy] + 1)/ 2 の値 */
	int  sxd_m, syd_m, dxd_m, dyd_m;    /* 計算用 */
	int  f_now, f_left, f_up;	/* 拡大用のドット情報 　　　*/


	dst = preamble->raster;
	dst_byte_size = (dst_x_bytes = preamble->byte_width)
					* (dyd_m = preamble->height);
	if (!(sxd_m = src_x_dots) || !(syd_m = src_y_dots)) return;
	if ((dxd_m = preamble->width) == src_x_dots && dyd_m == src_y_dots) {
		/* サイズが同じ:単純コピーでよい。*/
		while (dst_byte_size-- > 0) *dst++ = *raster++;
		return;
	}
	/* コピー先をゼロ・クリア */
	for (d = dst, n = dst_byte_size; n > 0; n--) *d++ = 0;

	src_x_bytes = ((src_x_dots + 7) >> 3);

	if (dxd_m <= src_x_dots && dyd_m <= src_y_dots) {
		/* 縮小の場合はNaochan!のアルゴリズムで */

		if (sxd_m > 1){
			sxd_m--;         			/* `src_x_dots' minus 1 */
			dxd_m--;					/* `dst_x_dots' minus 1 */
		}
		if (syd_m > 1){
			syd_m--;					/* `src_y_dots' minus 1 */
			dyd_m--;					/* `dst_y_dots' minus 1 */
		}

		f_up = ((long)src_y_dots*dyd_m + syd_m >= 0x8000L)?1:0;
		ty_half = syd_m >> 1;

		for (sx = 0; sx < src_x_dots; sx++) {
			dx = ( (long)sx * dxd_m + (sxd_m>>1) ) / sxd_m;
			for (sy = 0; sy < src_y_dots; sy++) {
				if (CHK_DOT(sx, sy)){
					dy = (f_up)? ((long)sy * dyd_m + ty_half) / syd_m:
								 (sy * dyd_m + ty_half) / syd_m;
						SET_DOT(dx, dy);
				}
			}
		}
		return;
	}

	/* 拡大の場合は吉澤氏と松田氏のアルゴリズムで */
	/* 線の太さは拡大率を丸めたもの */
	thick_x = (dxd_m + src_x_dots/2) / src_x_dots;
	tx_half = ((thick_x + 1) >> 1);
	thick_y = (dyd_m + src_y_dots/2) / src_y_dots;
	ty_half = ((thick_y + 1) >> 1);

	if (sxd_m > 1) sxd_m--;		/* `src_x_dots' minus 1 */
	dxd_m -= thick_x;			/* `dst_x_dots' minus thick_x */
	if (syd_m > 1) syd_m--;		/* `src_y_dots' minus 1 */
	dyd_m -= thick_y;			/* `dst_y_dots' minus thick_y */

	for (sy = 0; sy < src_y_dots; sy++) {
		dy0 = ((long)sy * dyd_m + syd_m/2) / syd_m;
		dy1 = dy0 + thick_y;
		dy0_m = dy0 - ty_half;
		dy1_m = dy1 - ty_half;
		for (sx = f_left = 0; sx < src_x_dots; f_left = f_now, sx++) {
			if ((f_now = CHK_DOT(sx, sy)) != 0) {
				dx0 = ((long)sx * dxd_m + sxd_m/2) / sxd_m;
				dx1 = dx0 + thick_x;
				for (dy = dy0; dy < dy1; dy++) {
					for (dx = dx0; dx < dx1; dx++)
						SET_DOT(dx,dy);
				}
				/* 隙間補正(左) */
				if (f_left) {
					dx = dx0 - 1;
					for (dy = dy0; dy < dy1; dy++)
						SET_DOT(dx,dy);
				}
				/* 隙間補正(上) */
				if (sy > 0) {
					if ((f_up = CHK_DOT(sx, sy-1)) != 0) {
						dy = dy0 - 1;
						for (dx = dx0; dx < dx1; dx++)
							SET_DOT(dx,dy);
					}
					dx0_m = dx0 - tx_half;
					dx1_m = dx1 - tx_half;
					/* 隙間補正(左上) */
					if (sx > 0) {
						if (!f_up){
							if (!f_left && CHK_DOT(sx-1, sy-1)) {
								for (dy = dy0_m; dy < dy1_m; dy++) {
									for (dx = dx0_m; dx < dx1_m; dx++)
											SET_DOT(dx,dy);
								}
							}
						}else if (f_left && CHK_DOT(sx-1,sy-1))
							SET_DOT(dx0 - 1, dy0 - 1);
					}
					/* 隙間補正(右上) */
					if (!f_up && sx < src_x_dots - 1) {
						if (CHK_DOT(sx+1, sy-1) && !CHK_DOT(sx+1, sy)) {
							dx1_p = dx1 + tx_half;
							for (dy = dy0_m; dy < dy1_m; dy++) {
								for (dx = dx0 + tx_half; dx < dx1_p; dx++)
									SET_DOT(dx,dy);
							}
						}
					}
				}
			}
		}
	}
}
 /* end of file getfont.c */
