| /* |
| * bdf2bmp -- output all glyphs in a bdf-font to a bmp-image-file |
| * version: 0.6 |
| * date: Wed Jan 10 23:59:03 2001 |
| * author: ITOU Hiroki (itouh@lycos.ne.jp) |
| */ |
| |
| /* |
| * Copyright (c) 2000,2001 ITOU Hiroki |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE |
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| */ |
| |
| /* modify if you want; color of spacing */ |
| #define COLOR_SPACING_RED 0x9a |
| #define COLOR_SPACING_GREEN 0x9a |
| #define COLOR_SPACING_BLUE 0xbd |
| /* modify if you want; out-of-dwidth over baseline */ |
| #define COLOR_OVERBL_RED 0xca |
| #define COLOR_OVERBL_GREEN 0xca |
| #define COLOR_OVERBL_BLUE 0xd8 |
| /* modify if you want; out-of-dwidth under baseline */ |
| #define COLOR_UNDERBL_RED 0xde |
| #define COLOR_UNDERBL_GREEN 0xde |
| #define COLOR_UNDERBL_BLUE 0xe7 |
| |
| #define VERBOSE |
| |
| #include <stdio.h> /* printf(), fopen(), fwrite() */ |
| #include <stdlib.h> /* malloc(), EXIT_SUCCESS, strtol(), exit() */ |
| #include <string.h> /* strcmp(), strcpy() */ |
| #include <limits.h> /* strtol() */ |
| #include <sys/stat.h> /* stat() */ |
| #include <sys/types.h> /* stat ? */ |
| #include <ctype.h> /* isdigit() */ |
| #include <stdint.h> /* int types */ |
| |
| #define LINE_CHARMAX 1000 /* number of max characters in bdf-font-file; number is without reason */ |
| #define FILENAME_CHARMAX 256 /* number of max characters in filenames; number is without reason */ |
| #define ON 1 /* number is without reason; only needs the difference to OFF */ |
| #define OFF 0 /* number is without reason; only needs the difference to ON */ |
| #define PARAM_MAX 10 /* max number of parameters */ |
| |
| #ifdef DEBUG |
| #define d_printf(message,arg) printf(message,arg) |
| #else /* not DEBUG */ |
| #define d_printf(message,arg) |
| #endif /* DEBUG */ |
| |
| #ifdef VERBOSE |
| #define v_printf(message,arg) printf(message,arg) |
| #else /* not VERBOSE */ |
| #define v_printf(message,arg) |
| #endif /* VERBOSE */ |
| |
| /* macro */ |
| #define STOREBITMAP() if(flagBitmap == ON){\ |
| memcpy(nextP, sP, length);\ |
| nextP += length;\ |
| } |
| |
| struct boundingbox{ |
| int w; /* width (pixel) */ |
| int h; /* height */ |
| int offx; /* offset y (pixel) */ |
| int offy; /* offset y */ |
| }; |
| |
| /* global var */ |
| struct boundingbox font; /* global boundingbox */ |
| static int chars; /* total number of glyphs in a bdf file */ |
| static int dwflag = ON; /* device width; only used for proportional-fonts */ |
| static int endian; /* 0 = MSB, 1 = LSB */ |
| |
| /* func prototype */ |
| void checkEndian(void); |
| void dwrite(const void *ptrP, int n, FILE *outP); |
| void writeBmpFile(unsigned char *bitmapP, int spacing, int colchar, FILE *bmpP); |
| void assignBitmap(unsigned char *bitmapP, char *glyphP, int sizeglyphP, struct boundingbox glyph, int dw); |
| int getfontline(char* lineP, int max, FILE* inputP); |
| unsigned char *readBdfFile(unsigned char *bitmapP, FILE *readP); |
| void printhelp(void); |
| int main(int argc, char *argv[]); |
| |
| |
| |
| /* |
| * Is your-CPU-byte-order MSB or LSB? |
| * MSB .. Most Significant Byte first (BigEndian) e.g. PowerPC, SPARC |
| * LSB .. Least Significant Byte first (LittleEndian) e.g. Intel Pentium |
| */ |
| void checkEndian(void){ |
| uint32_t uint32 = 0x12345678; |
| unsigned char *ucharP; |
| |
| ucharP = (unsigned char *)(&uint32); |
| if(*ucharP == 0x78){ |
| d_printf("LSB 0x%x\n", *ucharP); |
| endian = 1; |
| }else{ |
| d_printf("MSB 0x%x\n", *ucharP); |
| endian = 0; |
| } |
| } |
| |
| |
| |
| /* |
| * write to disk; with arranging LSBfirst(LittleEndian) byte order, |
| * because BMP-file is defined as LSB-first |
| */ |
| void dwrite(const void *varP, int n, FILE *outP){ |
| const unsigned char *p = varP; |
| int i; |
| unsigned char tmp; |
| |
| if(endian == 1){ |
| /* LSB; write without arranging */ |
| for(i=0; i<n; i++){ |
| tmp = fwrite(p+i, 1, sizeof(unsigned char), outP); |
| if(tmp != sizeof(unsigned char)){ |
| printf("error: cannot write an output-file\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| }else{ |
| /* MSB; write with arranging */ |
| for(i=n-1; i>=0; i--){ |
| tmp = fwrite(p+i, 1, sizeof(unsigned char), outP); |
| if(tmp != sizeof(unsigned char)){ |
| printf("error: cannot write an output-file\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| } |
| } |
| |
| |
| |
| /* |
| * 3. read bitmapAREA(onMemory) and write bmpFile with adding spacing |
| * BMP-file: noCompression(BI_RGB), 8bitColor, Windows-Win32 type |
| */ |
| void writeBmpFile(unsigned char *bitmapP, int spacing, int colchar, FILE *bmpP){ |
| long bmpw; /* bmp-image width (pixel) */ |
| long bmph; /* bmp-image height (pixel) */ |
| int bmppad; /* number of padding pixels */ |
| unsigned long bmpTotalSize; /* bmp filesize (byte) */ |
| /* bmp-lines needs to be long alined and padded with 0 */ |
| uint32_t uint32; |
| uint16_t uint16; |
| int32_t sint32; |
| unsigned char uchar; |
| int i,x,y,g,tmp; |
| int rowchar; /* number of row glyphs */ |
| int bx, by; |
| |
| /* bmp-image width */ |
| bmpw = (font.w+spacing)*colchar + spacing; |
| |
| /* bmp-image height */ |
| rowchar = (chars/colchar) + (chars%colchar!=0); |
| bmph = (font.h+spacing)*rowchar + spacing; |
| |
| v_printf(" BMP width = %d pixels\n", (int)bmpw); |
| v_printf(" BMP height = %d pixels\n", (int)bmph); |
| d_printf(" number of glyphs column=%d ", colchar); |
| d_printf("row=%d\n", rowchar); |
| |
| bmppad = ((bmpw + 3) / 4 * 4) - bmpw; |
| bmpTotalSize = (bmpw + bmppad) * bmph |
| + sizeof(int32_t)*11 + sizeof(int16_t)*5 + sizeof(char)*4*256; |
| v_printf(" BMP filesize = %d bytes\n", (int)bmpTotalSize); |
| |
| |
| /* |
| * BITMAPFILEHEADER struct |
| */ |
| uint16 = 0x4d42; /* 4d = 'M', 42 = 'B' */ |
| dwrite(&uint16, sizeof(uint16), bmpP); |
| uint32 = bmpTotalSize; |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| uint16 = 0x00; |
| dwrite(&uint16, sizeof(uint16), bmpP); /* reserved as 0 */ |
| dwrite(&uint16, sizeof(uint16), bmpP); /* reserved as 0 */ |
| |
| /* bfOffBits: offset to image-data array */ |
| uint32 = sizeof(int32_t)*11 + sizeof(int16_t)*5 + sizeof(char)*4*256; |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| |
| |
| /* |
| * BITMAPINFOHEADER struct |
| */ |
| uint32 = 40; /* when Windows-BMP, this is 40 */ |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| sint32 = bmpw; /* biWidth */ |
| dwrite(&sint32, sizeof(sint32), bmpP); |
| sint32 = bmph; /* biHeight: down-top */ |
| dwrite(&sint32, sizeof(sint32), bmpP); |
| uint16 = 1; /* biPlanes: must be 1 */ |
| dwrite(&uint16, sizeof(uint16), bmpP); |
| uint16 = 8; /* biBitCount: 8bitColor */ |
| dwrite(&uint16, sizeof(uint16), bmpP); |
| uint32 = 0; /* biCompression: noCompression(BI_RGB) */ |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| uint32 = 0; /* biSizeImage: when noComprsn, 0 is ok */ |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| sint32 = 0; /* biXPelsPerMeter: resolution x; 0 ok */ |
| dwrite(&sint32, sizeof(sint32), bmpP); |
| sint32 = 0; /* biYPelsPerMeter: res y; 0 is ok */ |
| dwrite(&sint32, sizeof(sint32), bmpP); |
| uint32 = 0; /* biClrUsed: optimized color palette; not used */ |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| uint32 = 0; /* biClrImportant: 0 is ok */ |
| dwrite(&uint32, sizeof(uint32), bmpP); |
| |
| /* |
| * RGBQUAD[256]: color palette |
| */ |
| /* palette[0]: background of glyphs */ |
| uchar = 0xff; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* rgbBlue: B */ |
| dwrite(&uchar, sizeof(uchar), bmpP); /* rgbGreen: G */ |
| dwrite(&uchar, sizeof(uchar), bmpP); /* rgbRed: R */ |
| uchar = 0; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* rgbReserved: must be 0 */ |
| |
| /* palette[1]: foreground of glyphs */ |
| uchar = 0; |
| for(i=0; i<4; i++) |
| dwrite(&uchar, sizeof(uchar), bmpP); /* palette[1]: #000000 */ |
| |
| /* palette[2]: spacing */ |
| uchar = COLOR_SPACING_BLUE; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* B */ |
| uchar = COLOR_SPACING_GREEN; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* G */ |
| uchar = COLOR_SPACING_RED; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* R */ |
| uchar = 0; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */ |
| |
| /* palette[3]: out of dwidth over baseline */ |
| uchar = COLOR_OVERBL_BLUE; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* B */ |
| uchar = COLOR_OVERBL_GREEN; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* G */ |
| uchar = COLOR_OVERBL_RED; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* R */ |
| uchar = 0; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */ |
| |
| /* palette[4]: out of dwidth; under baseline */ |
| uchar = COLOR_UNDERBL_BLUE; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* B */ |
| uchar = COLOR_UNDERBL_GREEN; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* G */ |
| uchar = COLOR_UNDERBL_RED; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* R */ |
| uchar = 0; |
| dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */ |
| |
| /* palette[5] to palette[255]: not used */ |
| for(i=5; i<256; i++){ |
| uchar = 0x00; /* palette[5to255]: #000000 */ |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| } |
| |
| /* |
| * IMAGE DATA array |
| */ |
| for(y=bmph-1; y>=0; y--){ |
| for(x=0; x<bmpw+bmppad; x++){ |
| if(x>=bmpw){ |
| /* padding: long(4bytes) aligned */ |
| uchar = 0; /* must pad with 0 */ |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| }else{ |
| if( (y%(font.h+spacing)<spacing) || (x%(font.w+spacing)<spacing) ){ |
| /* spacing */ |
| uchar = 2; /* fill palette[2] */ |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| }else{ |
| /* read bitmapAREA & write bmpFile */ |
| g = (x/(font.w+spacing)) + (y/(font.h+spacing)*colchar); |
| bx = x - (spacing*(g%colchar)) - spacing; |
| by = y - (spacing*(g/colchar)) - spacing; |
| tmp = g*(font.h*font.w) + (by%font.h)*font.w + (bx%font.w); |
| if(tmp >= chars*font.h*font.w){ |
| /* spacing over the last glyph */ |
| uchar = 2; /* fill palette[2] */ |
| }else |
| uchar = *( bitmapP + tmp); |
| dwrite(&uchar, sizeof(uchar), bmpP); |
| } |
| } |
| } |
| } |
| return; |
| } |
| |
| |
| |
| |
| /* |
| * 2. transfer bdf-font-file to bitmapAREA(onMemory) one glyph by one |
| */ |
| void assignBitmap(unsigned char *bitmapP, char *glyphP, int sizeglyphP, struct boundingbox glyph, int dw){ |
| static char *hex2binP[]= { |
| "0000","0001","0010","0011","0100","0101","0110","0111", |
| "1000","1001","1010","1011","1100","1101","1110","1111" |
| }; |
| int d; /* decimal number translated from hexNumber */ |
| int hexlen; /* a line length(without newline code) */ |
| char binP[LINE_CHARMAX]; /* binary strings translated from decimal number */ |
| static int nowchar = 0; /* number of glyphs handlled until now */ |
| char *tmpP; |
| char tmpsP[LINE_CHARMAX]; |
| int bitAh, bitAw; /* bitA width, height */ |
| int offtop, offbottom, offleft; /* glyph offset */ |
| unsigned char *bitAP; |
| unsigned char *bitBP; |
| int i,j,x,y; |
| |
| /* |
| * 2.1) change hexadecimal strings to a bitmap of glyph( called bitA) |
| */ |
| tmpP = strstr(glyphP, "\n"); |
| if(tmpP == NULL){ |
| /* if there is BITMAP\nENDCHAR in a given bdf-file */ |
| *glyphP = '0'; |
| *(glyphP+1) = '0'; |
| *(glyphP+2) = '\n'; |
| tmpP = glyphP + 2; |
| sizeglyphP = 3; |
| } |
| hexlen = tmpP - glyphP; |
| bitAw = hexlen * 4; |
| bitAh = sizeglyphP / (hexlen+1); |
| bitAP = malloc(bitAw * bitAh); /* address of bitA */ |
| if(bitAP == NULL){ |
| printf("error bitA malloc\n"); |
| exit(EXIT_FAILURE); |
| } |
| for(i=0,x=0,y=0; i<sizeglyphP; i++){ |
| if(glyphP[i] == '\n'){ |
| x=0; y++; |
| }else{ |
| sprintf(tmpsP, "0x%c", glyphP[i]); /* get one character from hexadecimal strings */ |
| d = (int)strtol(tmpsP,(char **)NULL, 16); |
| strcpy(binP, hex2binP[d]); /* change hexa strings to bin strings */ |
| for(j=0; j<4; j++,x++){ |
| if( bitAP+y*bitAw+x > bitAP+bitAw*bitAh ){ |
| printf("error: bitA pointer\n"); |
| exit(EXIT_FAILURE); |
| }else{ |
| *(bitAP + y*bitAw + x) = binP[j] - '0'; |
| } |
| } |
| } |
| } |
| |
| /* |
| * 2.2)make another bitmap area(called bitB) |
| * bitB is sized to FONTBOUNDINGBOX |
| */ |
| bitBP = malloc(font.w * font.h); /* address of bitB */ |
| if(bitBP == NULL){ |
| printf("error bitB malloc\n"); |
| exit(EXIT_FAILURE); |
| } |
| for(i=0; i<font.h; i++){ |
| for(j=0; j<font.w; j++){ |
| if(dwflag == OFF){ |
| /* all in boundingbox: palette[0] */ |
| *(bitBP + i*font.w + j) = 0; |
| }else{ |
| /* show the baselines and widths of glyphs */ |
| if( (j < (-1)*font.offx) || (j >= (-1)*font.offx+dw)){ |
| if(i < font.h - (-1)*font.offy){ |
| /* over baseline: palette[3] */ |
| *(bitBP + i*font.w + j) = 3; |
| }else{ |
| /* under baseline: palette[4] */ |
| *(bitBP + i*font.w + j) = 4; |
| } |
| }else{ |
| /* in dwidth: palette[0] */ |
| *(bitBP + i*font.w + j) = 0; |
| } |
| } |
| } |
| } |
| |
| /* |
| * 2.3) copy bitA inside BBX (smaller) to bitB (bigger) |
| * with offset-shifting; |
| * a scope beyond bitA is already filled with palette[0or3] |
| */ |
| offleft = (-1)*font.offx + glyph.offx; |
| /* offright = font.w - glyph.w - offleft; */ |
| |
| offbottom = (-1)*font.offy + glyph.offy; |
| offtop = font.h - glyph.h - offbottom; |
| |
| for(i=0; i<font.h; i++){ |
| if( i<offtop || i>=offtop+glyph.h ) |
| ; /* do nothing */ |
| else |
| for(j=0; j<font.w; j++) |
| if( j<offleft || j>=offleft+glyph.w ) |
| ; /* do nothing */ |
| else |
| *(bitBP + i*font.w + j) = *(bitAP + (i-offtop)*bitAw + (j-offleft)); |
| } |
| |
| /* |
| * 2.4) copy bitB to bitmapAREA |
| */ |
| for(i=0; i<font.h; i++) |
| for(j=0; j<font.w; j++) |
| *(bitmapP + (nowchar*font.w*font.h) + (i*font.w) + j) = *(bitBP + i*font.w + j); |
| |
| nowchar++; |
| free(bitAP); |
| free(bitBP); |
| } |
| |
| |
| /* |
| * read oneline from textfile |
| */ |
| int getfontline(char* lineP, int max, FILE* inputP){ |
| if (fgets(lineP, max, inputP) == NULL) |
| return 0; |
| else |
| return strlen(lineP); /* fgets returns strings included '\n' */ |
| } |
| |
| |
| /* |
| * 1. read BDF-file and transfer to assignBitmap() |
| */ |
| unsigned char *readBdfFile(unsigned char *bitmapP, FILE *readP){ |
| int i; |
| int length; |
| char sP[LINE_CHARMAX]; /* one line(strings) from bdf-font-file */ |
| static int cnt; /* only used in debugging: counter of appeared glyphs */ |
| struct boundingbox glyph; /* an indivisual glyph width, height,offset x,y */ |
| int flagBitmap = OFF; /* this line is bitmap-data?(ON) or no?(OFF) */ |
| char *tokP; /* top address of a token from strings */ |
| char *glyphP = NULL; /* bitmap-data(hexadecimal strings) */ |
| char* nextP = NULL; /* address of writing next in glyphP */ |
| int dw = 0; /* dwidth */ |
| static int bdfflag = OFF; /* the given bdf-file is valid or not */ |
| |
| while(1){ |
| length = getfontline(sP, LINE_CHARMAX, readP); |
| if((bdfflag == OFF) && (length == 0)){ |
| /* given input-file is not a bdf-file */ |
| printf("error: input-file is not a bdf file\n"); |
| exit(EXIT_FAILURE); |
| } |
| if(length == 0) |
| break; /* escape from while-loop */ |
| |
| /* remove carriage-return(CR) */ |
| for(i=0; i<length; i++){ |
| if(sP[i] == '\r'){ |
| sP[i] = '\n'; |
| length--; |
| } |
| } |
| |
| /* classify from the top character of sP */ |
| switch(sP[0]){ |
| case 'S': |
| if(bdfflag == OFF){ |
| /* top of the bdf-file */ |
| if(strncmp(sP, "STARTFONT ", 10) == 0){ |
| bdfflag = ON; |
| d_printf("startfont exists %d\n", bdfflag); |
| }else{ |
| /* given input-file is not a bdf-file */ |
| printf("error: input-file is not a bdf file\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| break; |
| case 'F': |
| if(strncmp(sP, "FONTBOUNDINGBOX ", 16) == 0){ |
| /* 16 means no comparing '\0' */ |
| |
| /* get font.w, font.h, font.offx, and font.offy */ |
| tokP = strtok(sP, " ");/* tokP addresses next space of FONTBOUNDINGBOX */ |
| tokP += (strlen(tokP)+1);/* tokP addresses top character of width in FONTBOUNDINGBOX */ |
| tokP = strtok(tokP, " ");/* set NUL on space after width */ |
| font.w = atoi(tokP); |
| tokP += (strlen(tokP)+1);/* height in FONTBOUNDINGBOX */ |
| tokP = strtok(tokP, " "); |
| font.h = atoi(tokP); |
| tokP += (strlen(tokP)+1); |
| tokP = strtok(tokP, " "); |
| font.offx = atoi(tokP); |
| tokP += (strlen(tokP)+1); |
| tokP = strtok(tokP, "\n"); |
| font.offy = atoi(tokP); |
| d_printf("global glyph width=%dpixels ",font.w); |
| d_printf("height=%dpixels\n",font.h); |
| d_printf("global glyph offset x=%dpixels ",font.offx); |
| d_printf("y=%dpixels\n",font.offy); |
| }else |
| STOREBITMAP(); |
| break; |
| case 'C': |
| if(strncmp(sP, "CHARS ", 6) == 0){ |
| /* get chars */ |
| tokP = strtok(sP, " "); |
| tokP += (strlen(tokP)+1); |
| tokP = strtok(tokP, "\n"); |
| chars = atoi(tokP); |
| v_printf(" Total glyphs = %d\n",chars); |
| cnt=0; |
| |
| /* allocate bitmapAREA */ |
| bitmapP = (unsigned char*)malloc(chars * font.h * font.w ); |
| if(bitmapP == NULL){ |
| printf("error malloc\n"); |
| exit(EXIT_FAILURE); |
| } |
| }else |
| STOREBITMAP(); |
| break; |
| case 'D': |
| if(strncmp(sP, "DWIDTH ", 7) == 0){ |
| /* get dw */ |
| tokP = strtok(sP, " "); |
| tokP += (strlen(tokP)+1); |
| tokP = strtok(tokP, " "); |
| dw = atoi(tokP); |
| }else |
| STOREBITMAP(); |
| break; |
| case 'B': |
| if(strncmp(sP, "BITMAP", 6) == 0){ |
| /* allocate glyphP */ |
| glyphP = (char*)malloc(font.w*font.h); /* allocate more room */ |
| if(glyphP == NULL){ |
| printf("error malloc bdf\n"); |
| exit(EXIT_FAILURE); |
| } |
| memset(glyphP, 0, font.w*font.h); /* zero clear */ |
| nextP = glyphP; |
| flagBitmap = ON; |
| }else if(strncmp(sP, "BBX ", 4) == 0){ |
| /* get glyph.offx, glyph.offy, glyph.w, and glyph.h */ |
| tokP = strtok(sP, " ");/* space after 'BBX' */ |
| tokP += (strlen(tokP)+1);/* top of width */ |
| tokP = strtok(tokP, " ");/* set NUL on space after width */ |
| glyph.w = atoi(tokP); |
| tokP += (strlen(tokP)+1);/* height */ |
| tokP = strtok(tokP, " "); |
| glyph.h = atoi(tokP); |
| tokP += (strlen(tokP)+1);/* offx */ |
| tokP = strtok(tokP, " "); |
| glyph.offx = atoi(tokP); |
| tokP += (strlen(tokP)+1);/* offy */ |
| tokP = strtok(tokP, "\n"); |
| glyph.offy = atoi(tokP); |
| /* d_printf("glyph width=%dpixels ",glyph.w); */ |
| /* d_printf("height=%dpixels\n",glyph.h); */ |
| /* d_printf("glyph offset x=%dpixels ",glyph.offx); */ |
| /* d_printf("y=%dpixels\n",glyph.offy); */ |
| }else |
| STOREBITMAP(); |
| break; |
| case 'E': |
| if(strncmp(sP, "ENDCHAR", 7) == 0){ |
| d_printf("\nglyph %d\n", cnt); |
| d_printf("%s\n",glyphP); |
| assignBitmap(bitmapP, glyphP, nextP - glyphP, glyph, dw); |
| flagBitmap = OFF; |
| free(glyphP); |
| cnt++; |
| }else |
| STOREBITMAP(); |
| break; |
| default: |
| STOREBITMAP(); |
| break; |
| }/* switch */ |
| }/* while */ |
| /* 'break' goto here */ |
| return bitmapP; |
| } |
| |
| |
| /* |
| * |
| */ |
| void printhelp(void){ |
| printf("bdf2bmp version 0.6\n"); |
| printf("Usage: bdf2bmp [-option] input-bdf-file output-bmp-file\n"); |
| printf("Option:\n"); |
| printf(" -sN spacing N pixels (default N=2)\n"); |
| printf(" N value can range from 0 to 32\n"); |
| printf(" -cN specifying N colomns in grid (default N=32)\n"); |
| printf(" N value can range from 1 to 1024\n"); |
| printf(" -w showing the baseline and the widths of glyphs\n"); |
| printf(" with gray colors\n"); |
| printf(" -i prompting whether to overwrite an existing file\n"); |
| printf(" -h print help\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| |
| |
| /* |
| * |
| */ |
| int main(int argc, char *argv[]){ |
| FILE *readP; |
| FILE *writeP; |
| char readFilename[FILENAME_CHARMAX] = "input.bdf"; |
| char writeFilename[FILENAME_CHARMAX] = "output.bmp"; |
| int i, j, tmp, n, dst, c; |
| char *sP; |
| unsigned char *bitmapP = NULL; /* address of bitmapAREA */ |
| int spacing = 2; /* breadth of spacing (default 2) */ |
| int flag; |
| int colchar = 32; /* number of columns(horizontal) (default 32) */ |
| char paramP[PARAM_MAX][LINE_CHARMAX]; /* parameter strings */ |
| int iflag = OFF; |
| struct stat fileinfo; |
| |
| /* |
| * deal with arguments |
| */ |
| if(argc < 2){ |
| /* printf("error: not enough arguments\n"); */ |
| printhelp(); |
| } |
| |
| /* formatting arguments */ |
| sP = calloc(LINE_CHARMAX, sizeof(char)); |
| if(sP == NULL){ |
| printf("error\n"); |
| exit(1); |
| } |
| for(i=1,dst=0,n=0; i<argc; i++){ |
| if(argv[i][0] == '-'){ |
| /* command-line options */ |
| for(j=1; j<(int)strlen(argv[i]); j++){ |
| if(argv[i][j]=='w' || |
| argv[i][j]=='i' || |
| argv[i][j]=='h' || |
| argv[i][j]=='v') |
| { |
| *(sP+dst) = '-'; dst++; |
| *(sP+dst) = argv[i][j]; dst++; |
| *(sP+dst) = '\0'; |
| strcpy(paramP[n], sP); dst=0; n++; |
| memset(sP,0,LINE_CHARMAX); |
| if(n >= PARAM_MAX){ |
| printf("error: too many arguments\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| }else if( (argv[i][j]=='s') || |
| (argv[i][j]=='c')) |
| { |
| *(sP+dst) = '-'; dst++; |
| *(sP+dst) = argv[i][j]; dst++; |
| }else if( isdigit(argv[i][j]) == 0 ){ |
| /* not [0-9] */ |
| printf("error: invalid option -- '%c'\n", argv[i][j]); |
| exit(EXIT_FAILURE); |
| }else if( argv[i][j+1] == '\0' ){ |
| *(sP+dst) = argv[i][j]; dst++; |
| *(sP+dst) = '\0'; |
| strcpy(paramP[n], sP); dst=0; n++; |
| if(n >= PARAM_MAX){ |
| printf("error: too many arguments\n"); |
| exit(EXIT_FAILURE); |
| } |
| }else{ |
| *(sP+dst) = argv[i][j]; dst++; |
| } |
| } |
| }else{ |
| /* not command-line options */ |
| for(j=0; j<(int)strlen(argv[i]); j++){ |
| *(sP+dst) = argv[i][j]; dst++; |
| } |
| *(sP+dst) = '\0'; |
| strcpy(paramP[n], sP); dst=0; n++; |
| memset(sP,0,LINE_CHARMAX); |
| if(n >= PARAM_MAX){ |
| printf("error: too many arguments\n"); |
| exit(EXIT_FAILURE); |
| } |
| } |
| } |
| free(sP); |
| |
| /* interpretting arguments */ |
| for(i=0, flag=0; i<n; i++){ |
| switch( paramP[i][0] ){ |
| case '-': |
| if(paramP[i][1] == 's') |
| spacing = atoi(¶mP[i][2]); |
| else if(paramP[i][1] == 'c') |
| colchar = atoi(¶mP[i][2]); |
| else if(paramP[i][1] == 'w') |
| dwflag = ON; |
| else if(paramP[i][1] == 'i') |
| iflag = ON; |
| else if( (paramP[i][1]=='v') || (paramP[i][1]=='h')) |
| printhelp(); |
| break; |
| default: |
| if(flag == 0){ |
| strcpy(readFilename, paramP[i]); |
| flag ++; |
| }else{ |
| strcpy(writeFilename, paramP[i]); |
| if(strcmp(readFilename, writeFilename) == 0){ |
| printf("error: input-filename and output-filename are same\n"); |
| exit(EXIT_FAILURE); |
| } |
| flag ++; |
| } |
| break; |
| } |
| } |
| |
| if(flag < 2){ |
| printf("error: not enough arguments\n"); |
| printf("Usage: bdf2bmp [-option] input-bdf-file output-bmp-file\n"); |
| exit(EXIT_FAILURE); |
| } |
| |
| /* colchar is limited from 1 to 1024 */ |
| if(colchar < 1) |
| colchar = 1; |
| else if(colchar > 1024) |
| colchar = 1024; |
| |
| /* spacing is limited from 0 to 32 */ |
| if(spacing < 0) |
| spacing = 0; |
| else if(spacing > 32) |
| spacing = 32; |
| |
| /* checkEndian */ |
| checkEndian(); |
| |
| /* |
| * prepare to read&write files |
| */ |
| readP = fopen(readFilename, "r"); |
| if(readP == NULL){ |
| printf("bdf2bmp: '%s' does not exist\n", readFilename); |
| exit(EXIT_FAILURE); |
| } |
| /* Does writeFilename already exist? */ |
| if((iflag==ON) && (stat(writeFilename, &fileinfo)==0)){ |
| fprintf(stderr, "bdf2bmp: overwrite '%s'? ", writeFilename); |
| c = fgetc(stdin); |
| if((c=='y') || (c=='Y')) |
| ; /* go next */ |
| else |
| /* printf("not overwrite\n"); */ |
| exit(EXIT_FAILURE); |
| } |
| writeP=fopen(writeFilename, "wb"); |
| if(writeP == NULL){ |
| printf("error: cannot write '%s'\n", writeFilename); |
| exit(EXIT_FAILURE); |
| } |
| |
| |
| /* read bdf-font-file */ |
| bitmapP = readBdfFile(bitmapP, readP); |
| fclose(readP); |
| |
| /* write bmp-image-file */ |
| writeBmpFile(bitmapP, spacing, colchar, writeP); |
| tmp = fclose(writeP); |
| if(tmp == EOF){ |
| printf("error: cannot write '%s'\n", writeFilename); |
| free(bitmapP); |
| exit(EXIT_FAILURE); |
| } |
| |
| free(bitmapP); |
| return EXIT_SUCCESS; |
| } |