upgtools: allow creation of a UPG archive + improvements
[maemo-rb.git] / tools / bdf2bmp.c
bloba00b39a5f3aa28074703b3bd1a16c2efd959aa05
1 /*
2 * bdf2bmp -- output all glyphs in a bdf-font to a bmp-image-file
3 * version: 0.6
4 * date: Wed Jan 10 23:59:03 2001
5 * author: ITOU Hiroki (itouh@lycos.ne.jp)
6 */
8 /*
9 * Copyright (c) 2000,2001 ITOU Hiroki
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 /* modify if you want; color of spacing */
35 #define COLOR_SPACING_RED 0x9a
36 #define COLOR_SPACING_GREEN 0x9a
37 #define COLOR_SPACING_BLUE 0xbd
38 /* modify if you want; out-of-dwidth over baseline */
39 #define COLOR_OVERBL_RED 0xca
40 #define COLOR_OVERBL_GREEN 0xca
41 #define COLOR_OVERBL_BLUE 0xd8
42 /* modify if you want; out-of-dwidth under baseline */
43 #define COLOR_UNDERBL_RED 0xde
44 #define COLOR_UNDERBL_GREEN 0xde
45 #define COLOR_UNDERBL_BLUE 0xe7
47 #define VERBOSE
49 #include <stdio.h> /* printf(), fopen(), fwrite() */
50 #include <stdlib.h> /* malloc(), EXIT_SUCCESS, strtol(), exit() */
51 #include <string.h> /* strcmp(), strcpy() */
52 #include <limits.h> /* strtol() */
53 #include <sys/stat.h> /* stat() */
54 #include <sys/types.h> /* stat ? */
55 #include <ctype.h> /* isdigit() */
56 #include <stdint.h> /* int types */
58 #define LINE_CHARMAX 1000 /* number of max characters in bdf-font-file; number is without reason */
59 #define FILENAME_CHARMAX 256 /* number of max characters in filenames; number is without reason */
60 #define ON 1 /* number is without reason; only needs the difference to OFF */
61 #define OFF 0 /* number is without reason; only needs the difference to ON */
62 #define PARAM_MAX 10 /* max number of parameters */
64 #ifdef DEBUG
65 #define d_printf(message,arg) printf(message,arg)
66 #else /* not DEBUG */
67 #define d_printf(message,arg)
68 #endif /* DEBUG */
70 #ifdef VERBOSE
71 #define v_printf(message,arg) printf(message,arg)
72 #else /* not VERBOSE */
73 #define v_printf(message,arg)
74 #endif /* VERBOSE */
76 /* macro */
77 #define STOREBITMAP() if(flagBitmap == ON){\
78 memcpy(nextP, sP, length);\
79 nextP += length;\
82 struct boundingbox{
83 int w; /* width (pixel) */
84 int h; /* height */
85 int offx; /* offset y (pixel) */
86 int offy; /* offset y */
89 /* global var */
90 struct boundingbox font; /* global boundingbox */
91 static int chars; /* total number of glyphs in a bdf file */
92 static int dwflag = ON; /* device width; only used for proportional-fonts */
93 static int endian; /* 0 = MSB, 1 = LSB */
95 /* func prototype */
96 void checkEndian(void);
97 void dwrite(const void *ptrP, int n, FILE *outP);
98 void writeBmpFile(unsigned char *bitmapP, int spacing, int colchar, FILE *bmpP);
99 void assignBitmap(unsigned char *bitmapP, char *glyphP, int sizeglyphP, struct boundingbox glyph, int dw);
100 int getfontline(char* lineP, int max, FILE* inputP);
101 unsigned char *readBdfFile(unsigned char *bitmapP, FILE *readP);
102 void printhelp(void);
103 int main(int argc, char *argv[]);
108 * Is your-CPU-byte-order MSB or LSB?
109 * MSB .. Most Significant Byte first (BigEndian) e.g. PowerPC, SPARC
110 * LSB .. Least Significant Byte first (LittleEndian) e.g. Intel Pentium
112 void checkEndian(void){
113 uint32_t uint32 = 0x12345678;
114 unsigned char *ucharP;
116 ucharP = (unsigned char *)(&uint32);
117 if(*ucharP == 0x78){
118 d_printf("LSB 0x%x\n", *ucharP);
119 endian = 1;
120 }else{
121 d_printf("MSB 0x%x\n", *ucharP);
122 endian = 0;
129 * write to disk; with arranging LSBfirst(LittleEndian) byte order,
130 * because BMP-file is defined as LSB-first
132 void dwrite(const void *varP, int n, FILE *outP){
133 const unsigned char *p = varP;
134 int i;
135 unsigned char tmp;
137 if(endian == 1){
138 /* LSB; write without arranging */
139 for(i=0; i<n; i++){
140 tmp = fwrite(p+i, 1, sizeof(unsigned char), outP);
141 if(tmp != sizeof(unsigned char)){
142 printf("error: cannot write an output-file\n");
143 exit(EXIT_FAILURE);
146 }else{
147 /* MSB; write with arranging */
148 for(i=n-1; i>=0; i--){
149 tmp = fwrite(p+i, 1, sizeof(unsigned char), outP);
150 if(tmp != sizeof(unsigned char)){
151 printf("error: cannot write an output-file\n");
152 exit(EXIT_FAILURE);
161 * 3. read bitmapAREA(onMemory) and write bmpFile with adding spacing
162 * BMP-file: noCompression(BI_RGB), 8bitColor, Windows-Win32 type
164 void writeBmpFile(unsigned char *bitmapP, int spacing, int colchar, FILE *bmpP){
165 long bmpw; /* bmp-image width (pixel) */
166 long bmph; /* bmp-image height (pixel) */
167 int bmppad; /* number of padding pixels */
168 unsigned long bmpTotalSize; /* bmp filesize (byte) */
169 /* bmp-lines needs to be long alined and padded with 0 */
170 uint32_t uint32;
171 uint16_t uint16;
172 int32_t sint32;
173 unsigned char uchar;
174 int i,x,y,g,tmp;
175 int rowchar; /* number of row glyphs */
176 int bx, by;
178 /* bmp-image width */
179 bmpw = (font.w+spacing)*colchar + spacing;
181 /* bmp-image height */
182 rowchar = (chars/colchar) + (chars%colchar!=0);
183 bmph = (font.h+spacing)*rowchar + spacing;
185 v_printf(" BMP width = %d pixels\n", (int)bmpw);
186 v_printf(" BMP height = %d pixels\n", (int)bmph);
187 d_printf(" number of glyphs column=%d ", colchar);
188 d_printf("row=%d\n", rowchar);
190 bmppad = ((bmpw + 3) / 4 * 4) - bmpw;
191 bmpTotalSize = (bmpw + bmppad) * bmph
192 + sizeof(int32_t)*11 + sizeof(int16_t)*5 + sizeof(char)*4*256;
193 v_printf(" BMP filesize = %d bytes\n", (int)bmpTotalSize);
197 * BITMAPFILEHEADER struct
199 uint16 = 0x4d42; /* 4d = 'M', 42 = 'B' */
200 dwrite(&uint16, sizeof(uint16), bmpP);
201 uint32 = bmpTotalSize;
202 dwrite(&uint32, sizeof(uint32), bmpP);
203 uint16 = 0x00;
204 dwrite(&uint16, sizeof(uint16), bmpP); /* reserved as 0 */
205 dwrite(&uint16, sizeof(uint16), bmpP); /* reserved as 0 */
207 /* bfOffBits: offset to image-data array */
208 uint32 = sizeof(int32_t)*11 + sizeof(int16_t)*5 + sizeof(char)*4*256;
209 dwrite(&uint32, sizeof(uint32), bmpP);
213 * BITMAPINFOHEADER struct
215 uint32 = 40; /* when Windows-BMP, this is 40 */
216 dwrite(&uint32, sizeof(uint32), bmpP);
217 sint32 = bmpw; /* biWidth */
218 dwrite(&sint32, sizeof(sint32), bmpP);
219 sint32 = bmph; /* biHeight: down-top */
220 dwrite(&sint32, sizeof(sint32), bmpP);
221 uint16 = 1; /* biPlanes: must be 1 */
222 dwrite(&uint16, sizeof(uint16), bmpP);
223 uint16 = 8; /* biBitCount: 8bitColor */
224 dwrite(&uint16, sizeof(uint16), bmpP);
225 uint32 = 0; /* biCompression: noCompression(BI_RGB) */
226 dwrite(&uint32, sizeof(uint32), bmpP);
227 uint32 = 0; /* biSizeImage: when noComprsn, 0 is ok */
228 dwrite(&uint32, sizeof(uint32), bmpP);
229 sint32 = 0; /* biXPelsPerMeter: resolution x; 0 ok */
230 dwrite(&sint32, sizeof(sint32), bmpP);
231 sint32 = 0; /* biYPelsPerMeter: res y; 0 is ok */
232 dwrite(&sint32, sizeof(sint32), bmpP);
233 uint32 = 0; /* biClrUsed: optimized color palette; not used */
234 dwrite(&uint32, sizeof(uint32), bmpP);
235 uint32 = 0; /* biClrImportant: 0 is ok */
236 dwrite(&uint32, sizeof(uint32), bmpP);
239 * RGBQUAD[256]: color palette
241 /* palette[0]: background of glyphs */
242 uchar = 0xff;
243 dwrite(&uchar, sizeof(uchar), bmpP); /* rgbBlue: B */
244 dwrite(&uchar, sizeof(uchar), bmpP); /* rgbGreen: G */
245 dwrite(&uchar, sizeof(uchar), bmpP); /* rgbRed: R */
246 uchar = 0;
247 dwrite(&uchar, sizeof(uchar), bmpP); /* rgbReserved: must be 0 */
249 /* palette[1]: foreground of glyphs */
250 uchar = 0;
251 for(i=0; i<4; i++)
252 dwrite(&uchar, sizeof(uchar), bmpP); /* palette[1]: #000000 */
254 /* palette[2]: spacing */
255 uchar = COLOR_SPACING_BLUE;
256 dwrite(&uchar, sizeof(uchar), bmpP); /* B */
257 uchar = COLOR_SPACING_GREEN;
258 dwrite(&uchar, sizeof(uchar), bmpP); /* G */
259 uchar = COLOR_SPACING_RED;
260 dwrite(&uchar, sizeof(uchar), bmpP); /* R */
261 uchar = 0;
262 dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */
264 /* palette[3]: out of dwidth over baseline */
265 uchar = COLOR_OVERBL_BLUE;
266 dwrite(&uchar, sizeof(uchar), bmpP); /* B */
267 uchar = COLOR_OVERBL_GREEN;
268 dwrite(&uchar, sizeof(uchar), bmpP); /* G */
269 uchar = COLOR_OVERBL_RED;
270 dwrite(&uchar, sizeof(uchar), bmpP); /* R */
271 uchar = 0;
272 dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */
274 /* palette[4]: out of dwidth; under baseline */
275 uchar = COLOR_UNDERBL_BLUE;
276 dwrite(&uchar, sizeof(uchar), bmpP); /* B */
277 uchar = COLOR_UNDERBL_GREEN;
278 dwrite(&uchar, sizeof(uchar), bmpP); /* G */
279 uchar = COLOR_UNDERBL_RED;
280 dwrite(&uchar, sizeof(uchar), bmpP); /* R */
281 uchar = 0;
282 dwrite(&uchar, sizeof(uchar), bmpP); /* must be 0 */
284 /* palette[5] to palette[255]: not used */
285 for(i=5; i<256; i++){
286 uchar = 0x00; /* palette[5to255]: #000000 */
287 dwrite(&uchar, sizeof(uchar), bmpP);
288 dwrite(&uchar, sizeof(uchar), bmpP);
289 dwrite(&uchar, sizeof(uchar), bmpP);
290 dwrite(&uchar, sizeof(uchar), bmpP);
294 * IMAGE DATA array
296 for(y=bmph-1; y>=0; y--){
297 for(x=0; x<bmpw+bmppad; x++){
298 if(x>=bmpw){
299 /* padding: long(4bytes) aligned */
300 uchar = 0; /* must pad with 0 */
301 dwrite(&uchar, sizeof(uchar), bmpP);
302 }else{
303 if( (y%(font.h+spacing)<spacing) || (x%(font.w+spacing)<spacing) ){
304 /* spacing */
305 uchar = 2; /* fill palette[2] */
306 dwrite(&uchar, sizeof(uchar), bmpP);
307 }else{
308 /* read bitmapAREA & write bmpFile */
309 g = (x/(font.w+spacing)) + (y/(font.h+spacing)*colchar);
310 bx = x - (spacing*(g%colchar)) - spacing;
311 by = y - (spacing*(g/colchar)) - spacing;
312 tmp = g*(font.h*font.w) + (by%font.h)*font.w + (bx%font.w);
313 if(tmp >= chars*font.h*font.w){
314 /* spacing over the last glyph */
315 uchar = 2; /* fill palette[2] */
316 }else
317 uchar = *( bitmapP + tmp);
318 dwrite(&uchar, sizeof(uchar), bmpP);
323 return;
330 * 2. transfer bdf-font-file to bitmapAREA(onMemory) one glyph by one
332 void assignBitmap(unsigned char *bitmapP, char *glyphP, int sizeglyphP, struct boundingbox glyph, int dw){
333 static char *hex2binP[]= {
334 "0000","0001","0010","0011","0100","0101","0110","0111",
335 "1000","1001","1010","1011","1100","1101","1110","1111"
337 int d; /* decimal number translated from hexNumber */
338 int hexlen; /* a line length(without newline code) */
339 char binP[LINE_CHARMAX]; /* binary strings translated from decimal number */
340 static int nowchar = 0; /* number of glyphs handlled until now */
341 char *tmpP;
342 char tmpsP[LINE_CHARMAX];
343 int bitAh, bitAw; /* bitA width, height */
344 int offtop, offbottom, offleft; /* glyph offset */
345 unsigned char *bitAP;
346 unsigned char *bitBP;
347 int i,j,x,y;
350 * 2.1) change hexadecimal strings to a bitmap of glyph( called bitA)
352 tmpP = strstr(glyphP, "\n");
353 if(tmpP == NULL){
354 /* if there is BITMAP\nENDCHAR in a given bdf-file */
355 *glyphP = '0';
356 *(glyphP+1) = '0';
357 *(glyphP+2) = '\n';
358 tmpP = glyphP + 2;
359 sizeglyphP = 3;
361 hexlen = tmpP - glyphP;
362 bitAw = hexlen * 4;
363 bitAh = sizeglyphP / (hexlen+1);
364 bitAP = malloc(bitAw * bitAh); /* address of bitA */
365 if(bitAP == NULL){
366 printf("error bitA malloc\n");
367 exit(EXIT_FAILURE);
369 for(i=0,x=0,y=0; i<sizeglyphP; i++){
370 if(glyphP[i] == '\n'){
371 x=0; y++;
372 }else{
373 sprintf(tmpsP, "0x%c", glyphP[i]); /* get one character from hexadecimal strings */
374 d = (int)strtol(tmpsP,(char **)NULL, 16);
375 strcpy(binP, hex2binP[d]); /* change hexa strings to bin strings */
376 for(j=0; j<4; j++,x++){
377 if( bitAP+y*bitAw+x > bitAP+bitAw*bitAh ){
378 printf("error: bitA pointer\n");
379 exit(EXIT_FAILURE);
380 }else{
381 *(bitAP + y*bitAw + x) = binP[j] - '0';
388 * 2.2)make another bitmap area(called bitB)
389 * bitB is sized to FONTBOUNDINGBOX
391 bitBP = malloc(font.w * font.h); /* address of bitB */
392 if(bitBP == NULL){
393 printf("error bitB malloc\n");
394 exit(EXIT_FAILURE);
396 for(i=0; i<font.h; i++){
397 for(j=0; j<font.w; j++){
398 if(dwflag == OFF){
399 /* all in boundingbox: palette[0] */
400 *(bitBP + i*font.w + j) = 0;
401 }else{
402 /* show the baselines and widths of glyphs */
403 if( (j < (-1)*font.offx) || (j >= (-1)*font.offx+dw)){
404 if(i < font.h - (-1)*font.offy){
405 /* over baseline: palette[3] */
406 *(bitBP + i*font.w + j) = 3;
407 }else{
408 /* under baseline: palette[4] */
409 *(bitBP + i*font.w + j) = 4;
411 }else{
412 /* in dwidth: palette[0] */
413 *(bitBP + i*font.w + j) = 0;
420 * 2.3) copy bitA inside BBX (smaller) to bitB (bigger)
421 * with offset-shifting;
422 * a scope beyond bitA is already filled with palette[0or3]
424 offleft = (-1)*font.offx + glyph.offx;
425 /* offright = font.w - glyph.w - offleft; */
427 offbottom = (-1)*font.offy + glyph.offy;
428 offtop = font.h - glyph.h - offbottom;
430 for(i=0; i<font.h; i++){
431 if( i<offtop || i>=offtop+glyph.h )
432 ; /* do nothing */
433 else
434 for(j=0; j<font.w; j++)
435 if( j<offleft || j>=offleft+glyph.w )
436 ; /* do nothing */
437 else
438 *(bitBP + i*font.w + j) = *(bitAP + (i-offtop)*bitAw + (j-offleft));
442 * 2.4) copy bitB to bitmapAREA
444 for(i=0; i<font.h; i++)
445 for(j=0; j<font.w; j++)
446 *(bitmapP + (nowchar*font.w*font.h) + (i*font.w) + j) = *(bitBP + i*font.w + j);
448 nowchar++;
449 free(bitAP);
450 free(bitBP);
455 * read oneline from textfile
457 int getfontline(char* lineP, int max, FILE* inputP){
458 if (fgets(lineP, max, inputP) == NULL)
459 return 0;
460 else
461 return strlen(lineP); /* fgets returns strings included '\n' */
466 * 1. read BDF-file and transfer to assignBitmap()
468 unsigned char *readBdfFile(unsigned char *bitmapP, FILE *readP){
469 int i;
470 int length;
471 char sP[LINE_CHARMAX]; /* one line(strings) from bdf-font-file */
472 static int cnt; /* only used in debugging: counter of appeared glyphs */
473 struct boundingbox glyph; /* an indivisual glyph width, height,offset x,y */
474 int flagBitmap = OFF; /* this line is bitmap-data?(ON) or no?(OFF) */
475 char *tokP; /* top address of a token from strings */
476 char *glyphP = NULL; /* bitmap-data(hexadecimal strings) */
477 char* nextP = NULL; /* address of writing next in glyphP */
478 int dw = 0; /* dwidth */
479 static int bdfflag = OFF; /* the given bdf-file is valid or not */
481 while(1){
482 length = getfontline(sP, LINE_CHARMAX, readP);
483 if((bdfflag == OFF) && (length == 0)){
484 /* given input-file is not a bdf-file */
485 printf("error: input-file is not a bdf file\n");
486 exit(EXIT_FAILURE);
488 if(length == 0)
489 break; /* escape from while-loop */
491 /* remove carriage-return(CR) */
492 for(i=0; i<length; i++){
493 if(sP[i] == '\r'){
494 sP[i] = '\n';
495 length--;
499 /* classify from the top character of sP */
500 switch(sP[0]){
501 case 'S':
502 if(bdfflag == OFF){
503 /* top of the bdf-file */
504 if(strncmp(sP, "STARTFONT ", 10) == 0){
505 bdfflag = ON;
506 d_printf("startfont exists %d\n", bdfflag);
507 }else{
508 /* given input-file is not a bdf-file */
509 printf("error: input-file is not a bdf file\n");
510 exit(EXIT_FAILURE);
513 break;
514 case 'F':
515 if(strncmp(sP, "FONTBOUNDINGBOX ", 16) == 0){
516 /* 16 means no comparing '\0' */
518 /* get font.w, font.h, font.offx, and font.offy */
519 tokP = strtok(sP, " ");/* tokP addresses next space of FONTBOUNDINGBOX */
520 tokP += (strlen(tokP)+1);/* tokP addresses top character of width in FONTBOUNDINGBOX */
521 tokP = strtok(tokP, " ");/* set NUL on space after width */
522 font.w = atoi(tokP);
523 tokP += (strlen(tokP)+1);/* height in FONTBOUNDINGBOX */
524 tokP = strtok(tokP, " ");
525 font.h = atoi(tokP);
526 tokP += (strlen(tokP)+1);
527 tokP = strtok(tokP, " ");
528 font.offx = atoi(tokP);
529 tokP += (strlen(tokP)+1);
530 tokP = strtok(tokP, "\n");
531 font.offy = atoi(tokP);
532 d_printf("global glyph width=%dpixels ",font.w);
533 d_printf("height=%dpixels\n",font.h);
534 d_printf("global glyph offset x=%dpixels ",font.offx);
535 d_printf("y=%dpixels\n",font.offy);
536 }else
537 STOREBITMAP();
538 break;
539 case 'C':
540 if(strncmp(sP, "CHARS ", 6) == 0){
541 /* get chars */
542 tokP = strtok(sP, " ");
543 tokP += (strlen(tokP)+1);
544 tokP = strtok(tokP, "\n");
545 chars = atoi(tokP);
546 v_printf(" Total glyphs = %d\n",chars);
547 cnt=0;
549 /* allocate bitmapAREA */
550 bitmapP = (unsigned char*)malloc(chars * font.h * font.w );
551 if(bitmapP == NULL){
552 printf("error malloc\n");
553 exit(EXIT_FAILURE);
555 }else
556 STOREBITMAP();
557 break;
558 case 'D':
559 if(strncmp(sP, "DWIDTH ", 7) == 0){
560 /* get dw */
561 tokP = strtok(sP, " ");
562 tokP += (strlen(tokP)+1);
563 tokP = strtok(tokP, " ");
564 dw = atoi(tokP);
565 }else
566 STOREBITMAP();
567 break;
568 case 'B':
569 if(strncmp(sP, "BITMAP", 6) == 0){
570 /* allocate glyphP */
571 glyphP = (char*)malloc(font.w*font.h); /* allocate more room */
572 if(glyphP == NULL){
573 printf("error malloc bdf\n");
574 exit(EXIT_FAILURE);
576 memset(glyphP, 0, font.w*font.h); /* zero clear */
577 nextP = glyphP;
578 flagBitmap = ON;
579 }else if(strncmp(sP, "BBX ", 4) == 0){
580 /* get glyph.offx, glyph.offy, glyph.w, and glyph.h */
581 tokP = strtok(sP, " ");/* space after 'BBX' */
582 tokP += (strlen(tokP)+1);/* top of width */
583 tokP = strtok(tokP, " ");/* set NUL on space after width */
584 glyph.w = atoi(tokP);
585 tokP += (strlen(tokP)+1);/* height */
586 tokP = strtok(tokP, " ");
587 glyph.h = atoi(tokP);
588 tokP += (strlen(tokP)+1);/* offx */
589 tokP = strtok(tokP, " ");
590 glyph.offx = atoi(tokP);
591 tokP += (strlen(tokP)+1);/* offy */
592 tokP = strtok(tokP, "\n");
593 glyph.offy = atoi(tokP);
594 /* d_printf("glyph width=%dpixels ",glyph.w); */
595 /* d_printf("height=%dpixels\n",glyph.h); */
596 /* d_printf("glyph offset x=%dpixels ",glyph.offx); */
597 /* d_printf("y=%dpixels\n",glyph.offy); */
598 }else
599 STOREBITMAP();
600 break;
601 case 'E':
602 if(strncmp(sP, "ENDCHAR", 7) == 0){
603 d_printf("\nglyph %d\n", cnt);
604 d_printf("%s\n",glyphP);
605 assignBitmap(bitmapP, glyphP, nextP - glyphP, glyph, dw);
606 flagBitmap = OFF;
607 free(glyphP);
608 cnt++;
609 }else
610 STOREBITMAP();
611 break;
612 default:
613 STOREBITMAP();
614 break;
615 }/* switch */
616 }/* while */
617 /* 'break' goto here */
618 return bitmapP;
625 void printhelp(void){
626 printf("bdf2bmp version 0.6\n");
627 printf("Usage: bdf2bmp [-option] input-bdf-file output-bmp-file\n");
628 printf("Option:\n");
629 printf(" -sN spacing N pixels (default N=2)\n");
630 printf(" N value can range from 0 to 32\n");
631 printf(" -cN specifying N colomns in grid (default N=32)\n");
632 printf(" N value can range from 1 to 1024\n");
633 printf(" -w showing the baseline and the widths of glyphs\n");
634 printf(" with gray colors\n");
635 printf(" -i prompting whether to overwrite an existing file\n");
636 printf(" -h print help\n");
637 exit(EXIT_FAILURE);
645 int main(int argc, char *argv[]){
646 FILE *readP;
647 FILE *writeP;
648 char readFilename[FILENAME_CHARMAX] = "input.bdf";
649 char writeFilename[FILENAME_CHARMAX] = "output.bmp";
650 int i, j, tmp, n, dst, c;
651 char *sP;
652 unsigned char *bitmapP = NULL; /* address of bitmapAREA */
653 int spacing = 2; /* breadth of spacing (default 2) */
654 int flag;
655 int colchar = 32; /* number of columns(horizontal) (default 32) */
656 char paramP[PARAM_MAX][LINE_CHARMAX]; /* parameter strings */
657 int iflag = OFF;
658 struct stat fileinfo;
661 * deal with arguments
663 if(argc < 2){
664 /* printf("error: not enough arguments\n"); */
665 printhelp();
668 /* formatting arguments */
669 sP = calloc(LINE_CHARMAX, sizeof(char));
670 if(sP == NULL){
671 printf("error\n");
672 exit(1);
674 for(i=1,dst=0,n=0; i<argc; i++){
675 if(argv[i][0] == '-'){
676 /* command-line options */
677 for(j=1; j<(int)strlen(argv[i]); j++){
678 if(argv[i][j]=='w' ||
679 argv[i][j]=='i' ||
680 argv[i][j]=='h' ||
681 argv[i][j]=='v')
683 *(sP+dst) = '-'; dst++;
684 *(sP+dst) = argv[i][j]; dst++;
685 *(sP+dst) = '\0';
686 strcpy(paramP[n], sP); dst=0; n++;
687 memset(sP,0,LINE_CHARMAX);
688 if(n >= PARAM_MAX){
689 printf("error: too many arguments\n");
690 exit(EXIT_FAILURE);
693 }else if( (argv[i][j]=='s') ||
694 (argv[i][j]=='c'))
696 *(sP+dst) = '-'; dst++;
697 *(sP+dst) = argv[i][j]; dst++;
698 }else if( isdigit(argv[i][j]) == 0 ){
699 /* not [0-9] */
700 printf("error: invalid option -- '%c'\n", argv[i][j]);
701 exit(EXIT_FAILURE);
702 }else if( argv[i][j+1] == '\0' ){
703 *(sP+dst) = argv[i][j]; dst++;
704 *(sP+dst) = '\0';
705 strcpy(paramP[n], sP); dst=0; n++;
706 if(n >= PARAM_MAX){
707 printf("error: too many arguments\n");
708 exit(EXIT_FAILURE);
710 }else{
711 *(sP+dst) = argv[i][j]; dst++;
714 }else{
715 /* not command-line options */
716 for(j=0; j<(int)strlen(argv[i]); j++){
717 *(sP+dst) = argv[i][j]; dst++;
719 *(sP+dst) = '\0';
720 strcpy(paramP[n], sP); dst=0; n++;
721 memset(sP,0,LINE_CHARMAX);
722 if(n >= PARAM_MAX){
723 printf("error: too many arguments\n");
724 exit(EXIT_FAILURE);
728 free(sP);
730 /* interpretting arguments */
731 for(i=0, flag=0; i<n; i++){
732 switch( paramP[i][0] ){
733 case '-':
734 if(paramP[i][1] == 's')
735 spacing = atoi(&paramP[i][2]);
736 else if(paramP[i][1] == 'c')
737 colchar = atoi(&paramP[i][2]);
738 else if(paramP[i][1] == 'w')
739 dwflag = ON;
740 else if(paramP[i][1] == 'i')
741 iflag = ON;
742 else if( (paramP[i][1]=='v') || (paramP[i][1]=='h'))
743 printhelp();
744 break;
745 default:
746 if(flag == 0){
747 strcpy(readFilename, paramP[i]);
748 flag ++;
749 }else{
750 strcpy(writeFilename, paramP[i]);
751 if(strcmp(readFilename, writeFilename) == 0){
752 printf("error: input-filename and output-filename are same\n");
753 exit(EXIT_FAILURE);
755 flag ++;
757 break;
761 if(flag < 2){
762 printf("error: not enough arguments\n");
763 printf("Usage: bdf2bmp [-option] input-bdf-file output-bmp-file\n");
764 exit(EXIT_FAILURE);
767 /* colchar is limited from 1 to 1024 */
768 if(colchar < 1)
769 colchar = 1;
770 else if(colchar > 1024)
771 colchar = 1024;
773 /* spacing is limited from 0 to 32 */
774 if(spacing < 0)
775 spacing = 0;
776 else if(spacing > 32)
777 spacing = 32;
779 /* checkEndian */
780 checkEndian();
783 * prepare to read&write files
785 readP = fopen(readFilename, "r");
786 if(readP == NULL){
787 printf("bdf2bmp: '%s' does not exist\n", readFilename);
788 exit(EXIT_FAILURE);
790 /* Does writeFilename already exist? */
791 if((iflag==ON) && (stat(writeFilename, &fileinfo)==0)){
792 fprintf(stderr, "bdf2bmp: overwrite '%s'? ", writeFilename);
793 c = fgetc(stdin);
794 if((c=='y') || (c=='Y'))
795 ; /* go next */
796 else
797 /* printf("not overwrite\n"); */
798 exit(EXIT_FAILURE);
800 writeP=fopen(writeFilename, "wb");
801 if(writeP == NULL){
802 printf("error: cannot write '%s'\n", writeFilename);
803 exit(EXIT_FAILURE);
807 /* read bdf-font-file */
808 bitmapP = readBdfFile(bitmapP, readP);
809 fclose(readP);
811 /* write bmp-image-file */
812 writeBmpFile(bitmapP, spacing, colchar, writeP);
813 tmp = fclose(writeP);
814 if(tmp == EOF){
815 printf("error: cannot write '%s'\n", writeFilename);
816 free(bitmapP);
817 exit(EXIT_FAILURE);
820 free(bitmapP);
821 return EXIT_SUCCESS;