/* j8sx2fontx16.c code: SASANO Takayoshi ---- public domain, no warranty. [charset=ISO-2022-JP] ●とりあえず 説明文書くの面倒だから、省略。 …ソースコード読めば分かると思うので。 */ #include #include #include /* FONTX2 header */ #define CODETYPE_ASCII 0 #define CODETYPE_KANJI 1 /* common */ typedef struct { unsigned char identifier[6]; unsigned char fontname[8]; unsigned char xsize; unsigned char ysize; unsigned char codetype; } __attribute__((packed)) FONTX2_HEADER; /* ascii */ typedef struct { FONTX2_HEADER h; unsigned char d[1]; } __attribute__((packed)) FONTX2_ASCII; /* sjis */ typedef struct { FONTX2_HEADER h; unsigned char tnum; unsigned char d[1]; } __attribute__((packed)) FONTX2_KANJI; typedef struct { unsigned short start; unsigned short end; } __attribute__((packed)) FONTX2_CODETABLE; static FONTX2_CODETABLE CodeTable_SJIS[] = { {0x8140, 0x817e}, {0x8180, 0x81ac}, /* symbol */ {0x824f, 0x8258}, /* number */ {0x8260, 0x8279}, /* alphabet (large) */ {0x8281, 0x829a}, /* alphabet (small) */ {0x829f, 0x82f1}, /* hiragana */ {0x8340, 0x837e}, {0x8380, 0x8396}, /* katakana */ {0x839f, 0x83b6}, /* greek (large) */ {0x83bf, 0x83d6}, /* greek (small) */ {0x8440, 0x8460}, /* russian (large) */ {0x8470, 0x847e}, {0x8480, 0x8491}, /* russian (small) */ {0x889f, 0x88fc}, /* kanji (JIS1) */ {0x8940, 0x897e}, {0x8980, 0x89fc}, {0x8a40, 0x8a7e}, {0x8a80, 0x8afc}, {0x8b40, 0x8b7e}, {0x8b80, 0x8bfc}, {0x8c40, 0x8c7e}, {0x8c80, 0x8cfc}, {0x8d40, 0x8d7e}, {0x8d80, 0x8dfc}, {0x8e40, 0x8e7e}, {0x8e80, 0x8efc}, {0x8f40, 0x8f7e}, {0x8f80, 0x8ffc}, {0x9040, 0x907e}, {0x9080, 0x90fc}, {0x9140, 0x917e}, {0x9180, 0x91fc}, {0x9240, 0x927e}, {0x9280, 0x92fc}, {0x9340, 0x937e}, {0x9380, 0x93fc}, {0x9440, 0x947e}, {0x9480, 0x94fc}, {0x9540, 0x957e}, {0x9580, 0x95fc}, {0x9640, 0x967e}, {0x9680, 0x96fc}, {0x9740, 0x977e}, {0x9780, 0x97fc}, {0x9840, 0x9872}, {0x989f, 0x98fc}, /* kanji (JIS2) */ {0x9940, 0x997e}, {0x9980, 0x99fc}, {0x9a40, 0x9a7e}, {0x9a80, 0x9afc}, {0x9b40, 0x9b7e}, {0x9b80, 0x9bfc}, {0x9c40, 0x9c7e}, {0x9c80, 0x9cfc}, {0x9d40, 0x9d7e}, {0x9d80, 0x9dfc}, {0x9e40, 0x9e7e}, {0x9e80, 0x9efc}, {0x9f40, 0x9f7e}, {0x9f80, 0x9ffc}, {0xe040, 0xe07e}, {0xe080, 0xe0fc}, {0xe140, 0xe17e}, {0xe180, 0xe1fc}, {0xe240, 0xe27e}, {0xe280, 0xe2fc}, {0xe340, 0xe37e}, {0xe380, 0xe3fc}, {0xe440, 0xe47e}, {0xe480, 0xe4fc}, {0xe540, 0xe57e}, {0xe580, 0xe5fc}, {0xe640, 0xe67e}, {0xe680, 0xe6fc}, {0xe740, 0xe77e}, {0xe780, 0xe7fc}, {0xe840, 0xe87e}, {0xe880, 0xe8fc}, {0xe940, 0xe97e}, {0xe980, 0xe9fc}, {0xea40, 0xea7e}, {0xea80, 0xeaa4}, }; struct ankindex { int index; unsigned char *string; }; struct ankindex anktable[] = { { 128, " ABCDEFGHIJKLMNOPQRSTUVWXYZabcde"}, {4224, "fghijklmnopqrstuvwxyz,. :;?! /`'"}, {6656, " 0123456789 "}, {6784, " \"()+- = <> \\$ %#@ * "}, {6912, " &~ {} _|[] ^ "}, { -1, NULL}, }; /* data buffer (in/out) */ #define BUFFERSIZE (2048 * 1024) static char InData[BUFFERSIZE]; static char OutData[BUFFERSIZE]; /* SJIS -> JIS */ static int _mbcjmstojis(int jms) { int low, high; high = (jms >> 8) & 0xff; low = jms & 0xff; if (low < 0x9f) { if (high < 0xa0) { high -= 0x81; high *= 2; high += 0x21; } else { high -= 0xe0; high *= 2; high += 0x5f; } if (low > 0x7f) low--; low -= 0x1f; } else { if (high < 0xa0) { high -= 0x81; high *= 2; high += 0x22; } else { high -= 0xe0; high *= 2; high += 0x60; } low -= 0x7e; } return (high << 8) | low; } /* ku/ten -> kanji index */ static int get_kanjino(int ku, int ten) { int n; if (ku >= 80) { n = (ku - 80) * 128 + (ten % 32) + 1024 * (ten / 32) + 5120; } else if (ku >= 16) { n = (ku - 16) * 128 + ten + 32; } else if (ku == 13) { if (ten >= 1 && ten <= 5) { n = (ten - 1) + 539; } else if (ten >= 6 && ten <= 20) { n = (ten - 6) + 4608; } else if (ten >= 21 && ten <= 30) { n = (ten - 21) + 3854; } else if (ten >= 32 && ten <= 47) { int t[] = {1, 3, 2, 0, 7, 8, 9, 10, -1, -1, 13, 11, 12, -1, -1, 16}; n = (t[ten - 32] < 0) ? -1 : (t[ten - 32] + 4744); } else if (ten >= 48 && ten <= 49) { n = (ten - 48) + 4638; } else if (ten >= 50 && ten <= 54) { int t[] = {0, 2, 3, 147, 7}; n = (t[ten - 50] < 0) ? -1 : (t[ten - 50] + 7680); } else if (ten >= 66 && ten <= 68) { int t[] = {2, 7, 0}; n = t[ten - 66] + 7689; } else if (ten >= 74 && ten <= 76) { n = (ten - 74) + 4634; } else if (ten == 80) { n = 7708; } else if (ten >= 81 && ten <= 92) { int t[] = {21, 1688, -1, 1689, 1687, 17, 16, -1, -1, 28, 8, 7}; n = (t[ten - 81] < 0) ? -1 : (t[ten - 81] + 640); } else { n = -1; // undefined } } else if (ku >= 8) { n = -1; // 8-15 ku: undefined } else if (ku == 2) { if (ten >= 1 && ten <= 14) { n = (ku + 8) * 128 + (ten % 32) + 1024 * (ten / 32); } else if (ten >= 26 && ten <= 33) { n = (ten - 26) + 641; } else if (ten >= 42 && ten <= 48) { n = (ten - 42) + 649; } else if (ten >= 60 && ten <= 74) { n = (ten - 60) + 656; } else if (ten == 82) { n = 671; } else if (ten >= 83 && ten <= 89) { n = (ten - 83) + 4736; } else { n = -1; // undefined } } else { n = (ku + 8) * 128 + (ten % 32) + 1024 * (ten / 32); } if (n >= 8192) n = -1; return n; } /* get font data (kanji) */ static void get_kanji_font(int sjis, unsigned char *buf, int offset) { int i, kuten, ku, ten, index; unsigned char *p; kuten = _mbcjmstojis(sjis) - 0x2020; ku = (kuten >> 8) & 0xff; ten = kuten & 0xff; index = get_kanjino(ku, ten); if (index < 0) { memset(buf, ~0, 32); return; } p = &InData[128 * index + offset + 96]; for (i = 0; i < 16; i++) { *buf++ = *p++; *buf++ = *p++; } return; } /* copy CodeTable */ static char *copy_table(char *dst, FONTX2_CODETABLE *src, int entry) { int i; /* table must be little-endian */ for (i = 0; i < entry; i++) { *dst++ = src[i].start & 0xff; *dst++ = (src[i].start >> 8) & 0xff; *dst++ = src[i].end & 0xff; *dst++ = (src[i].end >> 8) & 0xff; } return dst; } /* convert (Kanji) */ static void convert_kanji(char *filename, char *fontname, int offset) { int i, tnum, sjis, chr; unsigned char *d; FILE *fp; FONTX2_KANJI *f; memset(OutData, 0, sizeof(OutData)); f = (FONTX2_KANJI *)OutData; tnum = sizeof(CodeTable_SJIS) / sizeof(FONTX2_CODETABLE); /* create header */ strncpy(f->h.identifier, "FONTX2", sizeof(f->h.identifier)); strncpy(f->h.fontname, fontname, sizeof(f->h.fontname)); for (i = 0; i < sizeof(f->h.fontname); i++) { if (f->h.fontname[i] < 0x20) f->h.fontname[i] = 0x20; } f->h.xsize = 16; f->h.ysize = 16; f->h.codetype = CODETYPE_KANJI; f->tnum = tnum; /* make CodeTable */ d = f->d; d = copy_table(d, CodeTable_SJIS, tnum); chr = 0; /* convert font */ for (i = 0; i < tnum; i++) { for (sjis = CodeTable_SJIS[i].start; sjis <= CodeTable_SJIS[i].end; sjis++, chr++) { get_kanji_font(sjis, d, offset); d += 32; } } /* save result */ fp = fopen(filename, "wb"); if (fp != NULL) { fwrite(OutData, 1, (sizeof(FONTX2_HEADER) + tnum * sizeof(FONTX2_CODETABLE) + 32 * chr + 1), fp); } fclose(fp); return; } /* get ascii font */ static void get_ascii_font(int offset, unsigned char *buf) { int i, n; struct ankindex *t; unsigned char *c, *p, *b; for (t = anktable; t->string != NULL; t++) { for (n = 0, c = t->string; *c; n++, c++) { if (*c == ' ') continue; p = &InData[128 * (t->index + n) + offset + 96]; b = &buf[*c * 16]; for (i = 0; i < 16; i++) { *b++ = *p++; p++; } } } return; } /* convert (ASCII) */ static void convert_ascii(char *filename, char *fontname, int offset) { int i, j; FILE *fp; FONTX2_ASCII *f; unsigned char *p; memset(OutData, 0, sizeof(OutData)); f = (FONTX2_ASCII *)OutData; /* create header */ strncpy(f->h.identifier, "FONTX2", sizeof(f->h.identifier)); strncpy(f->h.fontname, fontname, sizeof(f->h.fontname)); for (i = 0; i < sizeof(f->h.fontname); i++) { if (f->h.fontname[i] < 0x20) f->h.fontname[i] = 0x20; } f->h.xsize = 16 / 2; f->h.ysize = 16; f->h.codetype = CODETYPE_ASCII; /* convert font (ASCII, 0x20-0x7f) */ get_ascii_font(offset, f->d); /* save result */ fp = fopen(filename, "wb"); if (fp != NULL) { fwrite(OutData, 1, sizeof(FONTX2_HEADER) + 256 * 16, fp); } fclose(fp); return; } /* entry */ int main(int argc, char *argv[]) { int result; FILE *fp; fp = fopen("j8sx0062.bin", "rb"); if (fp == NULL) { printf("j8sx0062.bin not found\n"); result = EXIT_FAILURE; goto fin0; } memset(InData, ~0, sizeof(InData)); fread(InData, 1, sizeof(InData), fp); convert_kanji("jpnzn16x.j8m", "J8SXMINC", 0); convert_ascii("jpnhn16x.j8m", "J8SXMINC", 0); convert_kanji("jpnzn16x.j8g", "J8SXGOTH", 0x00100000); convert_ascii("jpnhn16x.j8g", "J8SXGOTH", 0x00100000); result = EXIT_SUCCESS; //fin1: fclose(fp); fin0: return result; }