/* * fontxbanner -- $fontx2フォントをつかったバナー * * revision history * 0.0: Nov. 3, 1998 by Dai ISHIJIMA (SBCSフォントのみ) * 1.0: Apr. 19, 2000 (DBCSフォントも) * * usage: fontxbanner [-fn SBCSフォント] [-fk DBCSフォント] [SJIS文字列] */ #include #include #include #define NEWLINE '\n' #define EOS '\0' #define shift --argc; ++argv char *prog; #define isdbcs(x) (((0x80 <= ((unsigned char)(x))) \ && (((unsigned char)(x)) <= 0x9f)) \ || (0xe0 <= ((unsigned char)(x)))) #define mask(x) (0x80 >> ((x) % 8)) /*#define byte(x,y,w,h) (((x) / 8) * (h) + (h) - (y) - 1)*/ #define byte(x,y,w,h) ((((w) + 7) / 8) * (y) + ((x) / 8)) #define CHARS_SBCS 256 #define SBCS 0 #define DBCS 1 #define ID_LEN 6 #define NAM_LEN 8 typedef struct { unsigned short start; unsigned short end; } dbcstbl; /* $fontx2フォントのヘッダ */ typedef struct { char id[ID_LEN]; char name[NAM_LEN]; unsigned char width; unsigned char height; unsigned char type; int ntbl; dbcstbl *table; unsigned char *font; } fontx; /* フォントファイルの先頭を読む */ int readheader(FILE *fp, fontx *header) { fread(header->id, ID_LEN, 1, fp); if (strncmp(header->id, "FONTX2", ID_LEN) != 0) { return(1); } fread(header->name, NAM_LEN, 1, fp); header->width = (unsigned char)getc(fp); header->height = (unsigned char)getc(fp); header->type = (unsigned char)getc(fp); return(0); } /* SBCS (いわゆる半角文字) フォントを読み込む */ unsigned char *getsbcs(char c, int *width, int *height, char *fn) { static FILE *fp = NULL; static fontx font; static int fontsize; if (fp == NULL) { if (fn == NULL) { fprintf(stderr, "%s: no sbcs font file specified\n", prog); exit(1); } if ((fp = fopen(fn, "r")) == NULL) { fprintf(stderr, "%s: can't open font file: %s\n", prog, fn); exit(1); } readheader(fp, &font); fontsize = ((font.width + 7) / 8) * font.height; font.font = (unsigned char *)calloc(CHARS_SBCS, fontsize); fread(font.font, CHARS_SBCS, fontsize, fp); } *width = font.width; *height = font.height; return(&font.font[c * fontsize]); } unsigned short getshort(FILE *fp) { unsigned char lo, hi; lo = getc(fp); hi = getc(fp); return(lo + hi * 256); } /* 文字コードcのフォントが何番目に入っているかを調べる */ int dbcspos(int c, int nchars, int tabsiz, dbcstbl *table) { int i, n; i = 0; n = 0; while ((i < tabsiz) && ((c < table[i].start) || (table[i].end < c))) { n += (table[i].end - table[i].start) + 1; ++i; } /* if (i >= tabsiz) { fprintf(stderr, "char %04x not found\n", c); } */ n += c - table[i].start; if ((n < 0) || (nchars < n)) { n = 0; } fprintf(stderr, "%04x, %d\n", c, n); return(n); } unsigned char *getdbcs(int c, int *width, int *height, char *fk) { static FILE *fp = NULL; static fontx font; static int fontsize; int i; static int nchars; if (fp == NULL) { if (fk == NULL) { fprintf(stderr, "%s: no dbcs font file specified\n", prog); exit(1); } if ((fp = fopen(fk, "r")) == NULL) { fprintf(stderr, "%s: can't open font file: %s\n", prog, fk); exit(1); } readheader(fp, &font); fontsize = ((font.width + 7) / 8) * font.height; font.ntbl = (unsigned char)getc(fp); font.table = (dbcstbl *)calloc(font.ntbl, sizeof(dbcstbl)); nchars = 0; for (i = 0; i < font.ntbl; i++) { font.table[i].start = getshort(fp); font.table[i].end = getshort(fp); nchars += font.table[i].end - font.table[i].start + 1; } font.font = (unsigned char *)calloc(nchars, fontsize); fread(font.font, nchars, fontsize, fp); fprintf(stderr, "%d tables, %d chars\n", font.ntbl, nchars); } *width = font.width; *height = font.height; return(&font.font[dbcspos(c, nchars, font.ntbl, font.table) * fontsize]); } void putsbcs(unsigned char c, char *fn) { unsigned char *fontbuf; int width, height; int x, y; fontbuf = getsbcs(c, &width, &height, fn); for (x = 0; x < width; x++) { for (y = height - 1; y >= 0; y--) { if (fontbuf[byte(x, y, width, height)] & mask(x)) { putc('#', stdout); } else { putc('-', stdout); } } putc(NEWLINE, stdout); } } void putdbcs(unsigned char hi, unsigned char lo, char *fk) { unsigned char *fontbuf; int width, height; int x, y; int c; c = hi * 256 + lo; fontbuf = getdbcs(c, &width, &height, fk); for (x = 0; x < width; x++) { for (y = height - 1; y >= 0; y--) { if (fontbuf[byte(x, y, width, height)] & mask(x)) { putc('#', stdout); } else { putc('-', stdout); } } putc(NEWLINE, stdout); } } /* 文字列s をバナー表示 */ void banner(char *s, char *fn, char *fk) { while (*s != EOS) { if (isdbcs(*s)) { putdbcs(*s, *(s + 1), fk); ++s; } else { putsbcs(*s, fn); } ++s; } } /* 行末の改行を取り除く */ char *chop(char *s) { char *p; p = s; while (*p != EOS) { ++p; } --p; if (*p == NEWLINE) { p = EOS; } return(s); } void usage() { fprintf(stderr, "Usage: %s [option] [message]\n", prog); fprintf(stderr, " option:\n"); fprintf(stderr, "\t-fn \n"); fprintf(stderr, "\t-fk \n"); } void main(int argc, char *argv[]) { char *fn, *fk; char s[BUFSIZ]; fn = fk = NULL; prog = *argv; shift; while ((argc > 0) && (argv[0][0] == '-')) { if (strcmp(*argv, "--") == 0) { shift; break; } else if (strcmp(*argv, "-fn") == 0) { shift; fn = *argv; } else if (strcmp(*argv, "-fk") == 0) { shift; fk = *argv; } shift; } if (argc > 0) { while (argc > 0) { banner(*argv, fn, fk); shift; } } else { while (fgets(s, BUFSIZ, stdin) != NULL) { chop(s); banner(s, fn, fk); } } exit(0); } /* Local Variables: */ /* compile-command:"gcc -Wall -o fontxbanner fontxbanner.c" */ /* End: */