File:  [RetroPC.NET] / mkfont32 / win9x / Attic / font.cpp
Revision 1.2: download - view: text, annotated - select for diffs
Mon Jun 7 15:05:33 2004 JST (21 years, 4 months ago) by yui
Branches: MAIN
CVS tags: HEAD
fix x1 fonts (T.Yui)

#include	"compiler.h"
#include	"common.h"
#include	"dosio.h"
#include	"fontdata.h"
#include	"font.h"

typedef struct {
	int		adrs;
	int		data;
	int		size;
} FONTPATCH;

static FONTPATCH patchx1[] = {
					{0x00, 0x20, 0x1b},
					{0x1b, 0x1b, 0x05},
					{0x7f, 0x79, 0x01},
					{0x80, 0x40, 0x0f},
					{0x8f, 0x6e, 0x01},
					{0x90, 0x85, 0x0f},
					{0x9f, 0x6f, 0x01},
					{0xe0, 0x6c, 0x02},
					{0xe2, 0x68, 0x04},
					{0xe6, 0x64, 0x02},
					{0xe8, 0x70, 0x01},
					{0xe9, 0x7a, 0x08},
					{0xf1, 0x3b, 0x05},
					{0xf6, 0x73, 0x05},
					{0xfb, 0x72, 0x01},
					{0xfc, 0x71, 0x01},
					{0xfd, 0x82, 0x03}};

static FONTPATCH patchx68[] = {
					{0x00, 0x00, 0x20},
					{0x0b, 0x94, 0x02},
					{0x80, 0x96, 0x03}};

static FONTPATCH patchx68h[] = {
					{0x86, 0x99, 0x0a},
					{0x91, 0xa3, 0x0f},
					{0xe0, 0xb2, 0x1e}};

static BYTE jis90_83[] = "ιΛιςεy˜β}Ÿσζ|θςαζεAθΥζ˚βα融Ÿ·ηŽε’žw˜ΤεMβΔ";
static BYTE jis90_90[] = "ˆ±‰§ŠaŠhŠ–ŠΑŠΠŒz{ŽΗx‘G’Ω“v“Ž“““τ”ˆ•O–™–χ˜U";

static BYTE jis83_78[] = "‹Δ–Š—yŠ";
static BYTE jis83_83[] = "κŸκ κ‘κ’";	// © PC-98‚ΕŠJ”­‚΅‚Δ‚ι‚©‚η“Η‚ί‚ρc

static char *str_x68k[15] = {
						"@@@@@@@@@@@@¨©ͺ«",
						"@Ih”“•fij–{C|D^",
						"‚O‚P‚Q‚R‚S‚T‚U‚V‚W‚XGFƒ„H",
						"—‚`‚a‚b‚c‚d‚e‚f‚g‚h‚i‚j‚k‚l‚m‚n",
						"‚o‚p‚q‚r‚s‚t‚u‚v‚w‚x‚ymnOQ",
						"e‚‚‚‚ƒ‚„‚…‚†‚‡‚ˆ‚‰‚Š‚‹‚Œ‚‚Ž‚",
						"‚‚‘‚’‚“‚”‚•‚–‚—‚˜‚™‚šobpP@",
						"@@@@@@‚π‚Ÿ‚‘‚£‚₯‚§‚α‚γ‚ε‚Α",
						"@‚ ‚’‚€‚¦‚¨‚©‚«‚­‚―‚±‚³‚΅‚·‚Ή‚»",
						"@BuvAEƒ’ƒ@ƒBƒDƒFƒHƒƒƒ…ƒ‡ƒb",
						"[ƒAƒCƒEƒGƒIƒJƒLƒNƒPƒRƒTƒVƒXƒZƒ\",
						"ƒ^ƒ`ƒcƒeƒgƒiƒjƒkƒlƒmƒnƒqƒtƒwƒzƒ}",
						"ƒ~ƒ€ƒƒ‚ƒ„ƒ†ƒˆƒ‰ƒŠƒ‹ƒŒƒƒƒ“JK",
						"‚½‚Ώ‚Β‚Δ‚Ζ‚Θ‚Ι‚Κ‚Λ‚Μ‚Ν‚Π‚Σ‚Φ‚Ω‚ά",
						"‚έ‚ή‚ί‚ΰ‚β‚δ‚ζ‚η‚θ‚ι‚κ‚λ‚ν‚ρ@@"};


// ------------------------------------------------------------------------

static int getmonobmpsize(int x, int y) {

	return(sizeof(BITMAPINFOHEADER) + 4*2 + 
								(((x + 31) / 8) & ~3) * y);
}

static void setmonobmphead(BITMAPINFO *bi, int x, int y) {

	BYTE	i;

	ZeroMemory(&bi->bmiHeader, sizeof(BITMAPINFOHEADER));
	bi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	bi->bmiHeader.biWidth = x;
	bi->bmiHeader.biHeight = y;
	bi->bmiHeader.biPlanes = 1;
	bi->bmiHeader.biBitCount = 1;
	bi->bmiHeader.biCompression = BI_RGB;
	bi->bmiHeader.biSizeImage = (((x + 31) / 8) & ~3) * y;
	bi->bmiHeader.biXPelsPerMeter = 0;
	bi->bmiHeader.biYPelsPerMeter = 0;
	bi->bmiHeader.biClrUsed = 2;
	bi->bmiHeader.biClrImportant = 2;

	for (i=0; i<2; i++) {
		bi->bmiColors[i].rgbRed = (i ^ 1) - 1;
		bi->bmiColors[i].rgbGreen = (i ^ 1) - 1;
		bi->bmiColors[i].rgbBlue = (i ^ 1) - 1;
		bi->bmiColors[i].rgbReserved = PC_RESERVED;
	}
}
// ---------------------------------------------------------------------------

static LABEL WORD __fastcall jis2sjisex(WORD jis) {

		__asm {
				mov		ax, cx
				xor		dl, dl
				add		ah, 21h
				test	ah, 1
				je		short jis2sjis1a
				mov		dl, 5eh
jis2sjis1a:		sar		ah, 1
				add		al, dl
				xor		ah, 20h
				or		ah, 80h
				cmp		al, 60h
				jb		short jis2sjis1b
				inc		al
jis2sjis1b:		add		al, 1fh
				xchg	al, ah
				ret
		}
}

static WORD jis2sjis(WORD jis, BYTE jistype) {

	if (jis < 0x2121) {
		return(0x4081);
	}
	else if (jis < 0x3021) {
		BYTE	jisl = (BYTE)jis;
		switch(jis & 0xff00) {
			case 0x2100:
				break;
			case 0x2200:
				if (jisl < 0x2f) {
					break;
				}
				if ((jistype & FONT_JIS78) || (jisl < 0x3a)) {
					return(0x4081);
				}
				else if (jisl < 0x42) {
					break;
				}
				else if (jisl < 0x4a) {
					return(0x4081);
				}
				else if (jisl < 0x51) {
					break;
				}
				else if (jisl < 0x5c) {
					return(0x4081);
				}
				else if (jisl < 0x6b) {
					break;
				}
				else if (jisl < 0x72) {
					return(0x4081);
				}
				else if (jisl < 0x7a) {
					break;
				}
				else if (jisl < 0x7e) {
					return(0x4081);
				}
				break;

			case 0x2300:
				if (jisl < 0x30) {
					return(0x4081);
				}
				else if (jisl < 0x3a) {
					break;
				}
				else if (jisl < 0x41) {
					return(0x4081);
				}
				else if (jisl < 0x5b) {
					break;
				}
				else if ((jisl < 0x61) || (jisl > 0x7a)) {
					return(0x4081);
				}
				break;
			case 0x2400:
				if (jisl > 0x73) {
					return(0x4081);
				}
				break;
			case 0x2500:
				if (jisl > 0x76) {
					return(0x4081);
				}
				break;
			case 0x2600:
				if (((jisl > 0x38) && (jisl < 0x41)) || (jisl > 0x58)) {
					return(0x4081);
				}
				break;
			case 0x2700:
				if (((jisl > 0x41) && (jisl < 0x51)) || (jisl > 0x71)) {
					return(0x4081);
				}
				break;
			case 0x2800:
				return(0x4081);
			case 0x2d00:
				if ((jisl == 0x3f) || (jisl > 0x7c) ||
					((jisl > 0x56) && (jisl < 0x5f))) {
					return(0x4081);
				}
				break;
			default:
				return(0x4081);
		}
		return(jis2sjisex(jis));
	}
	else if (jis < 0x4f54) {
		return(jis2sjisex(jis));
	}
	else if (jis < 0x5021) {
		return(0x4081);
	}
	else if (jis < 0x737f) {
		return(jis2sjisex(jis));
	}
	else if (jis < 0x7921) {
		if ((jistype & (FONT_JIS83 | FONT_JIS90)) &&
			(jis >= 0x7421) && (jis <= 0x7424)) {
			return(jis2sjisex(jis));
		}
		return(0x4081);
	}
	else if (jis < 0x7c6f) {
		return(jis2sjisex(jis));
	}
	else if (jis < 0x7c71) {
		return(0x4081);
	}
	else if (jis < 0x7c7f) {
		return(jis2sjisex(jis));
	}
	return(0x4081);
}

static void cnvjis78_83(char *str) {

	int		i;

	while((*str) && (*(str+1))) {
		// jis78¨jis83
		for (i=0; jis83_78[i]; i+=2) {
			if (*(WORD *)str == *(WORD *)(&jis83_78[i])) {
				*(WORD *)str = *(WORD *)(&jis83_83[i]);
				break;
			}
		}
		str += 2;
	}
}

static void cnvjis83_90(char *str) {

	int		i;

	while((*str) && (*(str+1))) {
		// jis83©¨jis90
		for (i=0; jis90_83[i]; i+=2) {
			if (*(WORD *)str == *(WORD *)(&jis90_83[i])) {
				*(WORD *)str = *(WORD *)(&jis90_90[i]);
				break;
			}
			if (*(WORD *)str == *(WORD *)(&jis90_90[i])) {
				*(WORD *)str = *(WORD *)(&jis90_83[i]);
				break;
			}
		}
		str += 2;
	}
}

// ---------------------------------------------------------------------------

static BOOL getfont_sub(BYTE *dest, char *str, char *fontname,
									int fntx, int fnty, int bmpx, int bmpy) {

	HDC			hdc;
	HDC			hdcimage;
	HANDLE		hwork;
	BITMAPINFO	*work;
	HBITMAP		hBitmap;
	HBITMAP		hBitmapbak;
	BYTE		*image;
	HFONT		hfont;
	HFONT		hfontbak;
	RECT		rect;

	SetRect(&rect, 0, 0, bmpx, bmpy);
	if ((hwork = GlobalAlloc(GPTR, getmonobmpsize(bmpx, bmpy))) == NULL) {
		return(FAILURE);
	}
	if ((work = (BITMAPINFO *)GlobalLock(hwork)) == NULL) {
		GlobalFree(hwork);
		return(FAILURE);
	}
	setmonobmphead(work, bmpx, bmpy);
    hdc = GetDC(NULL);
	hBitmap = CreateDIBSection(hdc, work, DIB_RGB_COLORS,
												(void **)&image, NULL, 0);
	hdcimage = CreateCompatibleDC(hdc);
	ReleaseDC(NULL, hdc);
	hBitmapbak = (HBITMAP)SelectObject(hdcimage, hBitmap);
	SetDIBColorTable(hdcimage, 0, 2, work->bmiColors);

	hfont = CreateFont(fnty, fntx, FW_DONTCARE, FW_DONTCARE, FW_REGULAR,
						FALSE, FALSE, FALSE, SHIFTJIS_CHARSET,
						OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
						NONANTIALIASED_QUALITY, FIXED_PITCH, fontname);
	hfontbak = (HFONT)SelectObject(hdcimage, hfont);
	SetTextColor(hdcimage, RGB(255, 255, 255));
	SetBkColor(hdcimage, RGB(0, 0, 0));

	FillRect(hdcimage, &rect, (HBRUSH)GetStockObject(BLACK_BRUSH));
	TextOut(hdcimage, 0, 0, str, strlen(str));
	CopyMemory(dest, image, (((bmpx + 31) / 8) & ~3) * bmpy);

	SelectObject(hdcimage, hBitmapbak);
	DeleteObject(hBitmap);
	DeleteDC(hdcimage);

	GlobalUnlock(hwork);
	GlobalFree(hwork);
	return(SUCCESS);
}


static BOOL getfont(BYTE *dest, char *fontname, int base,
													int size, BYTE jistype) {

	int		i;
	char	textbuf[256];

	if (!base) {
		for (i=0; i<0x5f; i++) {
			textbuf[i] = (BYTE)(i + 0x20);
		}
		textbuf[0x5f] = ' ';
		textbuf[0x60] = ' ';
		for (i=0x01; i<0x40; i++) {
			textbuf[i+0x60] = (BYTE)(i + 0xa0);
		}
		textbuf[0xa0] = '\0';
	}
	else {
		*(WORD *)textbuf = 0x4081;
		for (i=1; i<0x5f; i++) {
			((WORD *)textbuf)[i] = jis2sjis((base << 8) + i + 0x20, jistype);
		}
		textbuf[i*2] = '\0';
		if (jistype & FONT_JIS78) {
			cnvjis78_83(textbuf);
		}
		if (jistype & (FONT_JIS78 | FONT_JIS83)) {
			cnvjis83_90(textbuf);
		}
	}
	return(getfont_sub(dest, textbuf, fontname,
									size, size*2, size*256, size*2));
}


// --------------------------------------------------------------------------

static void patchext2dat(BYTE *dst, FONTPATCH *src, int length) {

	BYTE	*p, *q;
	int		i;
	int		size;

	length /= sizeof(FONTPATCH);
	for (i=0; i<length; i++) {
		p = ext8 + (src[i].data * 8);
		q = dst + (src[i].adrs * 8);
		size = src[i].size * 8;
		CopyMemory(q, p, size);
	}
}

static void patchank2dat(BYTE *dst, FONTPATCH *src, int length) {

	BYTE	*p, *q;
	int		i;
	int		size;

	length /= sizeof(FONTPATCH);
	for (i=0; i<length; i++) {
		p = (BYTE *)(&ext16[src[i].data * 8]);
		q = dst + (src[i].adrs * 16);
		size = src[i].size * 16;
		CopyMemory(q, p, size);
	}
}


// --------------------------------------------------------------------------

#if 0
static LABEL WORD __fastcall jis2sjisx(WORD jis) {

		__asm {
				mov		ax, cx
				xor		dl, dl
				add		ah, 21h
				test	ah, 1
				je		short jis2sjis1a
				mov		dl, 5eh
jis2sjis1a:		sar		ah, 1
				add		al, dl
				xor		ah, 20h
				or		ah, 80h
				cmp		al, 60h
				jb		short jis2sjis1b
				inc		al
jis2sjis1b:		add		al, 1fh
				ret
		}
}

static void cpyknj2x1fnt(BYTE *dst, BYTE *src, int jish) {

	BYTE	*q;
	WORD	sjis;
	int		i, j;

	jish <<= 8;
	for (i=0x01; i<0x5f; i++) {
		src += 2;
		q = NULL;
		sjis = jis2sjisx((WORD)(jish + i + 0x20));
		if (sjis >= 0x8140 && sjis < 0x84c0) {
			q = dst + 0x00000 + ((DWORD)(sjis - 0x8140) << 5);
		}
		else if (sjis >= 0x8890 && sjis < 0xa000) {
			q = dst + 0x07000 + ((DWORD)(sjis - 0x8890) << 5);
		}
		else if (sjis >= 0xe040 && sjis < 0xeab0) {
			q = dst + 0x35e00 + ((DWORD)(sjis - 0xe040) << 5);
		}
		if (q) {
			for (j=0; j<16; j++) {
				*(WORD *)q = *(WORD *)(&src[(15-j)*256]);
				q += 2;
			}
		}
	}
}

BOOL makex1font(char *dirname, char *fontface) {

	HANDLE		hwork;
	BYTE		*work;
	FILEH		fh;
	BYTE		fnt[256*16];
	int			i, j;
	BYTE		*p;
	BYTE		*q;
	int			jish;

	if ((hwork = GlobalAlloc(GPTR, 306176)) == NULL) {
		return(FAILURE);
	}
	if ((work = (BYTE *)GlobalLock(hwork)) == NULL) {
		GlobalFree(hwork);
		return(FAILURE);
	}

	ZeroMemory(work, 0x800);
	CopyMemory(work + 0x20*8, ank8, 0x60*8);
	CopyMemory(work + 0xa0*8, ank8+0x60*8, 0x40*8);
	patchext2dat(work, patchx1, sizeof(patchx1));

	strcpy((char *)fnt, dirname);
	strcat((char *)fnt, "FNT0808.X1");
	if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
		file_write(fh, work, 0x800);
		file_close(fh);
	}

	ZeroMemory(work, 0x1000);
	getfont(fnt, fontface, 0, 8, FONT_JIS78);
	p = fnt;
	q = work + 0x20*16;
	for (j=0x20; j<0x7f; j++, p++) {
		for (i=0; i<16; i++) {
			*q++ = p[(15-i)*256];
		}
	}
	p = fnt + 0x61;
	q = work + 0xa1*16;
	for (j=0xa1; j<0xe0; j++, p++) {
		for (i=0; i<16; i++) {
			*q++ = p[(15-i)*256];
		}
	}
	patchank2dat(work, patchx1, sizeof(patchx1));

	strcpy((char *)fnt, dirname);
	strcat((char *)fnt, "FNT0816.X1");
	if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
		file_write(fh, work, 0x1000);
		file_close(fh);
	}

	ZeroMemory(work, 306176);
	for (jish=0x01; jish<0x74; jish++) {
		getfont(fnt, fontface, jish+0x20, 8, FONT_JIS78);
		cpyknj2x1fnt(work, fnt, jish+0x20);
	}

	strcpy((char *)fnt, dirname);
	strcat((char *)fnt, "FNT1616.X1");
	if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
		file_write(fh, work, 306176);
		file_close(fh);
	}
	GlobalUnlock(hwork);
	GlobalFree(hwork);
	return(SUCCESS);
}
#endif


// --------------------------------------------------------------------------

static void cpysmall2cgrom(BYTE *dst, BYTE *src, int line) {

	int		i, j;

	dst += 0x5e * 32 * line;
	for (i=0; i<0x5e; i++) {
		src += 2;
		for (j=16; j--;) {
			*(WORD *)dst = *(WORD *)(src + j * 256);
			dst += 2;
		}
	}
}

static void cpybig2cgrom(BYTE *dst, BYTE *src, int line) {

	int		i, j;

	dst += 0x5e * 72 * line;
	for (i=0; i<0x5e; i++) {
		src += 3;
		for (j=24; j--;) {
			*dst++ = *(src + j * 384 + 0);
			*dst++ = *(src + j * 384 + 1);
			*dst++ = *(src + j * 384 + 2);
		}
	}
}

static void cpy12fnt2cgrom(BYTE *dst, BYTE *src, int y) {

	int		i, j;

	for (i=0; i<8; i++) {
		for (j=0; j<y; j++) {
			*(WORD *)dst = (*(WORD *)(&src[(23-j)*32])) & 0xf0ff;
			dst += 2;
		}
		for (j=0; j<y; j++) {
			*dst++ = (src[(23-j)*32+1] << 4) | (src[(23-j)*32+2] >> 4);
			*dst++ = (src[(23-j)*32+2] << 4);
		}
		src += 3;
	}
}

BOOL makecgromdat(char *dirname, char *fontface) {

	HANDLE		hwork;
	BYTE		*work;
	FILEH		fh;
	BYTE		fnt[24*256*24/8];
	int			i, j;
	BYTE		*p;
	BYTE		*q;
	int			jish;

	if ((hwork = GlobalAlloc(GPTR, 0xc0000)) == NULL) {
		return(FAILURE);
	}
	if ((work = (BYTE *)GlobalLock(hwork)) == NULL) {
		GlobalFree(hwork);
		return(FAILURE);
	}
	ZeroMemory(work, 0xc0000);

	// 8x8
	CopyMemory(work + 0x3a000 + 0x20*8, ank8, 0x60*8);
	CopyMemory(work + 0x3a000 + 0xa0*8, ank8+0x60*8, 0x40*8);
	patchext2dat(work + 0x3a000, patchx68, sizeof(patchx68));
	patchext2dat(work + 0x3a000, patchx68h, sizeof(patchx68h));

	// 8x16
	getfont(fnt, fontface, 0, 8, FONT_JIS90);
	p = fnt;
	q = work + 0x3a800 + 0x20*16;
	for (j=0x20; j<0x7f; j++, p++) {
		for (i=0; i<16; i++) {
			*q++ = p[(15-i)*256];
		}
	}
	p = fnt + 0x61;
	q = work + 0x3a800 + 0xa1*16;
	for (j=0xa1; j<0xe0; j++, p++) {
		for (i=0; i<16; i++) {
			*q++ = p[(15-i)*256];
		}
	}
	patchank2dat(work + 0x3a800, patchx68, sizeof(patchx68));
	patchank2dat(work + 0x3a800, patchx68h, sizeof(patchx68h));

	// 16x16
	for (jish=0; jish<7; jish++) {
		getfont(fnt, fontface, jish+0x21, 8, FONT_JIS90);
		cpysmall2cgrom(work, fnt, jish);
	}
	for (jish=0; jish<0x45; jish++) {
		getfont(fnt, fontface, jish+0x30, 8, FONT_JIS90);
		cpysmall2cgrom(work, fnt, jish+8);
	}
	CopyMemory(work + 0x5e*32*7, x68k16, 32*32);

	// 24x24
	for (jish=0; jish<7; jish++) {
		getfont(fnt, fontface, jish+0x21, 12, FONT_JIS90);
		cpybig2cgrom(work + 0x40000, fnt, jish);
	}
	for (jish=0; jish<0x45; jish++) {
		getfont(fnt, fontface, jish+0x30, 12, FONT_JIS90);
		cpybig2cgrom(work + 0x40000, fnt, jish+8);
	}
	CopyMemory(work + 0x40000 + 0x5e*72*7, x68k24, 72*32);

	// 12x12
	for (i=0; i<0x0f; i++) {
		getfont_sub(fnt, str_x68k[i], fontface, 6, 12, 256, 24);
		cpy12fnt2cgrom(work + 0x3b800 + (i+1)*24*16, fnt, 12);
	}
	CopyMemory(work + 0x3b800 + 24*1, x68c12, 24*0x1b);
	CopyMemory(work + 0x3b800 + 24*0x80, &x68c12[0x1b*24/2], 24*0x03);

	// 12x24
	for (i=0; i<0x0f; i++) {
		getfont_sub(fnt, str_x68k[i], fontface, 6, 24, 256, 24);
		cpy12fnt2cgrom(work + 0x3d000 + (i+1)*16*2*24, fnt, 24);
	}
	CopyMemory(work + 0x3d000 + 48*1, x68c24, 48*0x1b);
	CopyMemory(work + 0x3d000 + 48*0x80, &x68c24[0x1b*48/2], 48*0x03);

	strcpy((char *)fnt, dirname);
	strcat((char *)fnt, "CGROM.DAT");
	if ((fh = file_create((char *)fnt)) != (FILEH)-1) {
		file_write(fh, work, 0xc0000);
		file_close(fh);
	}
	GlobalUnlock(hwork);
	GlobalFree(hwork);
	return(SUCCESS);
}

RetroPC.NET-CVS <cvs@retropc.net>