home *** CD-ROM | disk | FTP | other *** search
- #include "fntool.h"
-
- typedef struct {
- int bbw,bbh;
- int bbx,bby;
- } bbox;
-
- static char **bmp;
- static bbox fontbb;
- static bbox charbb;
- static int ascent;
- static int descent;
- static int defchar;
-
- static void badbdf(char *msg)
- {
- fatalerr("invalid \".bdf\" file: \"%s\" -- %s",inname,msg);
- }
-
- static void readbitmap(void)
- {
- char *bp;
- int ww = charbb.bbw;
- int hh = charbb.bbh;
- int y0 = fontbb.bbh - hh - (charbb.bby - fontbb.bby);
- int x,y,bits;
-
- if((charbb.bbw > fontbb.bbw) || (charbb.bbh > fontbb.bbh))
- badbdf("bounding box error");
- if((charbb.bbx < fontbb.bbx) || (charbb.bby < fontbb.bby))
- badbdf("bounding box error");
- if(bmp == NULL)
- bmp = makebytemap(fontbb.bbw,fontbb.bbh);
- setbytemap(bmp,0,0,0,fontbb.bbw,fontbb.bbh);
- for(y = 0; y < hh; y++) {
- bp = readline();
- for(bits = x = 0; x < ww; x++) {
- if((x & 3) == 0) {
- bits = *bp++;
- if(!isxdigit(bits)) {
- if(x == 0) badbdf("invalid bitmap digit");
- bits = 0;
- }
- else if(isdigit(bits)) bits -= '0';
- else if(isupper(bits)) bits -= ('A' - 10);
- else bits -= ('a' - 10);
- }
- bmp[y0+y][x] = (bits & 8) ? 1 : 0;
- bits <<= 1;
- }
- }
- }
-
- static chr *buildchar(chr *temp)
- {
- int wdt = temp->width;
- int pos = 0;
- int cpy = charbb.bbw;
- chr *result;
-
- if(charbb.bbx > 0)
- pos = charbb.bbx;
- else if(charbb.bbx < 0)
- wdt -= charbb.bbx;
- if((pos + cpy) > wdt) wdt = pos + cpy;
- temp->width = wdt;
- temp->bmp = makebytemap(wdt,fnt.height);
- copybytemap(temp->bmp,pos,0,bmp,0,0,cpy,fontbb.bbh);
- result = safemalloc(sizeof(chr));
- *result = *temp;
- return(result);
- }
-
- static void readchar(void)
- {
- char *buff;
- chr *cp,newch;
- chr *prv,*nxt;
-
- memset(&newch,0,sizeof(chr));
- newch.code = (-1);
- charbb = fontbb;
- for( ; ; ) {
- buff = readline();
- if(strmatch(buff,"ENCODING")) {
- sscanf(buff,"ENCODING %d",&newch.code);
- continue;
- }
- if(strmatch(buff,"DWIDTH")) {
- sscanf(buff,"DWIDTH %d",&newch.width);
- continue;
- }
- if(strmatch(buff,"BBX")) {
- sscanf(buff,
- "BBX %d %d %d %d",
- &charbb.bbw,&charbb.bbh,&charbb.bbx,&charbb.bby
- );
- continue;
- }
- if(strmatch(buff,"BITMAP")) {
- readbitmap();
- break;
- }
- }
- if(newch.code < 0) return;
- cp = buildchar(&newch);
- for(prv = NULL,nxt = fnt.chars; nxt != NULL; prv = nxt,nxt = nxt->next) {
- if(nxt->code == cp->code) badbdf("repeated character");
- if(nxt->code > cp->code) break;
- }
- cp->next = nxt;
- *(prv ? &prv->next : &fnt.chars) = cp;
- }
-
- static void scanstr(char *line,char *buf)
- {
- if((line = strchr(line,'"')) != NULL) for( ; ; ) {
- if(*++line != '"') {
- *buf++ = *line;
- if(*line == '\0') break;
- continue;
- }
- if(line[1] == '"') {
- *buf++ = '"';
- line++;
- continue;
- }
- break;
- }
- *buf = '\0';
- }
-
- static void readfont(void)
- {
- char *buff;
- char token[100];
- int ii;
-
- bmp = NULL;
- for( ; ; ) {
- buff = readline();
- if(strmatch(buff,"FONTBOUNDINGBOX")) {
- sscanf(buff,
- "FONTBOUNDINGBOX %d %d %d %d",
- &fontbb.bbw,&fontbb.bbh,&fontbb.bbx,&fontbb.bby
- );
- if(fontbb.bbh > fnt.height) fnt.height = fontbb.bbh;
- continue;
- }
- if(strmatch(buff,"FAMILY_NAME")) {
- scanstr(buff,fnt.family);
- continue;
- }
- if(strmatch(buff,"WEIGHT_NAME")) {
- scanstr(buff,token);
- if(strmatch(token,"bold"))
- strcpy(fnt.weight,"bold");
- else if(strmatch(token,"thin"))
- strcpy(fnt.weight,"thin");
- continue;
- }
- if(strmatch(buff,"SLANT")) {
- scanstr(buff,token);
- switch(tolower(token[0])) {
- case 'i':
- case 'o':
- strcpy(fnt.slant,"ital");
- break;
- }
- continue;
- }
- if(strmatch(buff,"SPACING")) {
- scanstr(buff,token);
- switch(tolower(token[0])) {
- case 'p':
- fnt.isfixed = 0;
- break;
- case 'c':
- case 'm':
- fnt.isfixed = 1;
- break;
- }
- continue;
- }
- if(strmatch(buff,"PIXEL_SIZE")) {
- sscanf(buff,"PIXEL_SIZE %d",&ii);
- if(ii > fnt.height) fnt.height = ii;
- continue;
- }
- if(strmatch(buff,"FONT_DESCENT")) {
- sscanf(buff,"FONT_DESCENT %d",&descent);
- continue;
- }
- if(strmatch(buff,"FONT_ASCENT")) {
- sscanf(buff,"FONT_ASCENT %d",&ascent);
- continue;
- }
- if(strmatch(buff,"DEFAULT_CHAR")) {
- sscanf(buff,"DEFAULT_CHAR %d",&defchar);
- continue;
- }
- if(strmatch(buff,"FONT ")) {
- strcat(notes,buff);
- continue;
- }
- if(strmatch(buff,"COPYRIGHT")) {
- strcat(notes,buff);
- continue;
- }
- if(strmatch(buff,"COMMENT")) {
- strcat(notes,&buff[8]);
- continue;
- }
- if(strmatch(buff,"STARTCHAR")) {
- readchar();
- buff = readline();
- if(!strmatch(buff,"ENDCHAR")) badbdf("missing \"ENDCHAR\" line");
- continue;
- }
- if(strmatch(buff,"ENDFONT")) break;
- }
- if(bmp != NULL) free(bmp);
- }
-
- static void fillblank(void)
- {
- chr *cp,*defc,*new;
-
- defc = getchr(defchar);
- if(defc == NULL) defc = getchr(' ');
- if(defc == NULL) defc = getchr(0);
- if(defc == NULL) defc = fnt.chars;
- fnt.minchar = fnt.chars->code;
- for(cp = fnt.chars; cp != NULL; cp = cp->next) {
- if((cp->next != NULL) && ((cp->code + 1) != cp->next->code)) {
- new = safemalloc(sizeof(chr));
- *new = *defc;
- new->bmp = makebytemap(defc->width,fnt.height);
- copybytemap(new->bmp,0,0,defc->bmp,0,0,defc->width,fnt.height);
- new->code = cp->code + 1;
- new->next = cp->next;
- cp->next = new;
- }
- fnt.maxchar = cp->code;
- }
- }
-
- static void fixwidth(void)
- {
- chr *cp;
- char **newbmp;
- int pad;
-
- computewidth();
- if(fnt.maxwidth == fnt.minwidth) return;
- for(cp = fnt.chars; cp != NULL; cp = cp->next) {
- if(cp->width == fnt.maxwidth) continue;
- pad = fnt.maxwidth - cp->width;
- if((pad & 1) != 0) {
- int maxcol = -1;
- int mincol = cp->width + 1;
- int ii;
- for(ii = 0; ii < cp->width; ii++) {
- if(colbit(cp->bmp,ii)) {
- if(ii > maxcol) maxcol = ii;
- if(ii < mincol) mincol = ii;
- }
- }
- if(maxcol >= mincol) {
- if(mincol > (cp->width - maxcol - 1))
- pad >>= 1;
- else pad = (pad >> 1) + 1;
- }
- }
- else pad >>= 1;
- newbmp = makebytemap(fnt.maxwidth,fnt.height);
- copybytemap(newbmp,pad,0,cp->bmp,0,0,cp->width,fnt.height);
- free(cp->bmp);
- cp->bmp = newbmp;
- cp->width = fnt.maxwidth;
- }
- }
-
- void readbdf()
- {
- ascent = 0;
- descent = 0;
- defchar = 0;
- readfont();
- fillblank();
- if(fnt.isfixed) fixwidth();
- fnt.baseline = fontbb.bbh + fontbb.bby;
- fnt.undwidth = (fnt.height / 20) + 1;
- }
-