// #include #include #include #include #define isInvalidSJIS(x) \ ( (((x) & 0x00ff) < 0x0040) || ((x) < 0x8000) || \ (((x) >= 0xa000) && ((x) < 0xe000)) ) /* 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 int XSize; // character size (X) static int YSize; // character size (Y) static int XChar; // characters of X axis static int YChar; // characters of Y axis static int XPixel; // total pixels (X) static int YPixel; // total pixels (Y) static int PxBufSize; // size of pixel buffer; static uint8_t *Buf, *PxBuf; static size_t BufSize; int loadfile(char *filename) { FILE *fp; int result; fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "loadfile: %s open error\n", filename); result = -1; goto fin0; } fseek(fp, 0, SEEK_END); BufSize = ftell(fp); fseek(fp, 0, SEEK_SET); Buf = calloc(BufSize, 2); // XXX if (Buf == NULL) { fprintf(stderr, "loadfile: memory allocation error\n"); result = -1; goto fin1; } fread(Buf, BufSize, 1, fp); result = 0; fin1: fclose(fp); fin0: return result; } int savefile(char *filename) { int result; FILE *fp; fp = fopen(filename, "w"); if (fp == NULL) { fprintf(fp, "savefile: %s open error\n", filename); result = -1; goto fin0; } fprintf(fp, "P4\n%d %d\n", XPixel, YPixel); fwrite(PxBuf, PxBufSize, 1, fp); result = 0; fclose(fp); fin0: return result; } uint8_t *draw_char(int x, int y, uint8_t *p) { int i, j, xb; x /= 8; xb = XSize / 8; for (i = y; i < (y + YSize); i++) { for (j = x; j < (x + xb); j++) { PxBuf[i * (XPixel / 8) + j] = ~*p; p++; } } return p; } void draw_ascii(void) { int i, x, y; FONTX2_ASCII *h; uint8_t *p; h = (FONTX2_ASCII *)Buf; p = h->d; for (i = 0; i < 256; i++) { x = (i % XChar) * XSize; y = (i / XChar) * YSize; p = draw_char(x, y, p); } } void draw_kanji(void) { int i, j, x, y; FONTX2_KANJI *h; FONTX2_CODETABLE *t; uint8_t *p; h = (FONTX2_KANJI *)Buf; t = (FONTX2_CODETABLE *)h->d; p = (uint8_t *)&t[h->tnum]; for (i = 0; i < h->tnum; i++) { for (j = t[i].start; j <= t[i].end; j++) { if (isInvalidSJIS(j)) { fprintf(stderr, "invaid code %x\n", j); continue; } x = ((j & 0xff) - 0x40) * XSize; y = (j >> 8) & 0xff; y -= (y < 0xe0) ? 0x80 : 0xc0; y *= YSize; p = draw_char(x, y, p); } } } int main(int argc, char *argv[]) { FONTX2_HEADER *h; if (argc < 3) { fprintf(stderr, "usage: %s [infile] [outfile]\n", argv[0]); goto fin0; } if (loadfile(argv[1]) < 0) { goto fin0; } h = (FONTX2_HEADER *)Buf; XSize = (h->xsize + 7) & ~7; YSize = h->ysize; switch(h->codetype) { case CODETYPE_ASCII: XChar = 32; YChar = 8; break; case CODETYPE_KANJI: XChar = 0xc0; YChar = 0x40; break; default: fprintf(stderr, "unknown code type, abort\n"); goto fin1; } XPixel = XSize * XChar; YPixel = YSize * YChar; PxBufSize = XPixel * YPixel; PxBuf = malloc(PxBufSize); memset(PxBuf, ~0, PxBufSize); // clear all pixel if (PxBuf == NULL) { fprintf(stderr, "malloc failed\n"); goto fin1; } switch (h->codetype) { case CODETYPE_ASCII: draw_ascii(); break; case CODETYPE_KANJI: draw_kanji(); break; } savefile(argv[2]); free(PxBuf); fin1: free(Buf); fin0: return 0; }