/****************************************************************** A simple HBF 'API' by Yidao CAI Created on October 12, 1993 Last modified on January 26, 1995 All Rights Reserved Main Change: HBFPATH now can point to several paths, and current directory will be automatically added to the path (i.e. no need to specify it in HBFPATH). Also fixed a bug. It now handles GB/B5/JIS/KSC and 2-byte unicode. This 'API' (if it can be called an API at all) preforms the basic function of getting the bitmap of a character. It is intended to users who prefer an API with simpler functions and less codes. It should work on all platforms with minimum modification. It is free and can be modified to fit your needs, but I expect you properly credit my work. There is no warranty. Old functional protocal is used. Change if your compiler doesn't like it. Send comments and report bugs to cai@neurophys.wisc.edu You must call HBFopen() before call HBFgetBitmap(), and you need to call HBFclose() before you make another HBFopen() call unless the previous HBFopen() call is unsuccessful. A sample application is enclosed at the end of this file. int HBFopen(char *hbffile) Open HBF file (hbffile) and bitmap files, prepare storage space (buffer) for subsequent call of HBFgetBitmap(), get sizes (mx, my and CHsize) of bitmap. Both the HBF file name (hbffile) and the bitmap file name are relative to the 'root', i.e. it uses 'root' + 'hbffile/bitmap-file' to open a bitmap file or HBF file. By convention, the bitmap files should be in the same directory as the corresponding HBF file, but here the routine simply find the first one that matches, in the order of paths in HBFPATH. Note: in previous version, the HBF file name (hbffile) is absolute. int HBFgetBitmap(unsigned int code) Get the bitmap of character 'code' and store it in 'buffer'. It reqires the 'code' in GR format (with high bit set, except for 2-byte unicode). Only 2-byte codes are supported. void HBFclose() Close HBF, clear storage. FILE *Rfopen(char *fn, char *mod) Open a file with name 'root + fn' and with mode 'mod', used by HBFopen(). It will try all paths specified by HBFPATH, together with the current directory. Return NULL if all fail. int getroot() --- Optional Get the paths defined in HBFPATH and store it in 'root' for subsequent use. This function needs , . **** VMS/unix: no change is needed. **** DOS: you may need to change calloc to farcalloc, free to farfree, or whatever appropriate, depending on the memory model you use. int RotateMirrorBitmap(unsigned char *a) --- Optional Transpose the bitmap. Not tested for non-square bitmaps. Return values 1: normal -2: can't open HBF file -3: can't open bitmap file -4: out of range character -5: more than 2 byte-2-ranges -6: Not enough memory -7: Some system could not read Hexdecimal numbers properly, (e.g., NeXT), refer to neurophys.wisc.edu: pub/cn/00readme.0 for solution *******************************************************************/ /* The declaration below should be included in your .h file or put at the beginning of your program. You may also split the declaration and the rest into hbf.h and hbf.c as shown */ /* hbf.h */ #ifdef __MSDOS__ # define msdos #else # ifdef VMS /* nothing */ # else # define Unix 1 /* if not DOS or VMS */ # endif #endif #ifdef msdos #include #endif struct Roots {char *s; struct Roots *p;} *root; int mx, my; /* width, height of bitmap */ int CHsize; /* size of bitmap, or length of buffer */ unsigned char *buffer; /* store the bitmap of each char, updated on each call of HBFgetBitmap() */ struct Bytes {unsigned int l; unsigned int h; unsigned int a;} *b2; struct HBFrange {unsigned int l; unsigned int h; long offset; char bmfname[50]; FILE *fp;} *seg; int nb2, nseg; int GL=1; /* HBF file in GL format, default GL (MSB not set) */ void HBFclose(); FILE *HBF; /* hbf.c #include #include #include #include "hbf.h" */ int HBFopen(hbffile) char *hbffile; { int j, k, m; char cst[120]; FILE *Rfopen(); if ((HBF=Rfopen(hbffile, "r"))==NULL) return -2; while (fgets(cst, 119, HBF)!=NULL) if (strncmp(cst, "HBF_BITMAP_BOUNDING_BOX", 23)==0) break; sscanf(cst, "%*s%d%d", &mx, &my); CHsize=my*((mx+7)/8); if (buffer!=NULL) free(buffer); buffer = (unsigned char *) calloc(CHsize+1, sizeof(unsigned char)); if (buffer==NULL) return -6; while (fgets(cst, 119, HBF)!=NULL) if (strncmp(cst, "HBF_START_BYTE_2_RANGES", 23)==0) break; sscanf(cst, "%*s%d", &nb2); b2 = (struct Bytes *) calloc(nb2, sizeof(struct Bytes)); if (b2==NULL) return -6; for (j=0; j= 0x80) GL=0; if (b2[j].a==1) return -7; } while (fgets(cst, 119, HBF)!=NULL) if (strncmp(cst, "HBF_START_CODE_RANGES", 21)==0) break; sscanf(cst, "%*s%d", &nseg); seg = (struct HBFrange *) calloc(nseg, sizeof(struct HBFrange)); if (seg==NULL) return -6; for (j=0; j0) { for (m=0; m= seg[i].l && ch <= seg[i].h) { /* treat as if segment starts at lowest byte 2, then compensate */ b2off = seg[i].l%256 - b2[0].l; k = ch - seg[i].l + b2off; j = ch%256; k /= 256; if (nb2==1) addr = k*b2[0].a + j - b2off; else if (nb2==2) { addr = k*(b2[0].a + b2[1].a) + j - off; if (j > b2[0].a) addr -= (b2[1].l-b2[0].h-1); if (off > b2[0].a) addr += (b2[1].l-b2[0].h-1); } else /* can't handle yet, but it seems enough for now */ return -5; addr = addr*CHsize + seg[i].offset; fseek(seg[i].fp, addr, 0); return (int) fread(buffer, CHsize, 1, seg[i].fp); } j=0; while (js); strcat(cst, fn); /* fprintf(stderr, "cst: %s\n", cst); */ if ((fp=fopen(cst, mod))!=NULL) return fp; if (rt!=NULL) rt = rt->p; } while (rt!=NULL); return NULL; } getroot() { char *s, *t; int n, c = ';'; /* dos */ struct Roots *rt; root = (struct Roots *) calloc(1, sizeof(struct Roots)); if (root == NULL) return -6; rt = root; root->p = NULL; root->s=NULL; s=getenv("HBFPATH"); /* fprintf(stderr, "HBFPATH: %s\n", s);*/ #ifdef VMS c = ','; #endif #if Unix c = ':'; #endif do { if (root->s!=NULL && rt->p==NULL) { rt->p = (struct Roots *) calloc(1, sizeof(struct Roots)); if (rt->p==NULL) return -6; rt = rt->p; rt->p = NULL; } if (s!=NULL) t = strchr(s, c); else t = NULL; if (t!=NULL) n = t-s; else n = (s==NULL)? 0 : strlen(s); if ( (rt->s = (char *) calloc(n+2, sizeof(char))) == NULL) return -6; if (n) { strncpy (rt->s, s, n); s += n; if (t!=NULL) s++; #ifdef msdos if (rt->s[n-1] != '\\') strcat(rt->s, "\\"); #endif #if Unix if (rt->s[n-1] != '/') strcat(rt->s, "/"); #endif } else { (rt->s)[0] = '\0'; s=NULL; } } while (s!=NULL); /* for debug rt=root; do { printf("rt->s: .%s.\n", rt->s); if (rt!=NULL) rt = rt->p; } while (rt!=NULL); */ return 1; } /* Below is a sample application of the above API. Uncomment this part, move the next three #include <...> lines to top of this program, then compile and run. #include #include #include main(argc, argv) int argc; char *argv[]; { int j, k; unsigned int ch; char s[100]; if (argc<3) { fprintf(stderr, "usage: %s hbf_file char ...\n", argv[0]); exit(0); } getroot(); strcpy(s, argv[1]); HBFopen(s); for (j=2; j