/* * bdfindex.c - Make an index file of BDF font * * Programmmed by Hirotsugu Kakugawa, Hiroshima University * E-Mail: kakugawa@se.hiroshima-u.ac.jp * * Edition History * 27 Dec 1995 Index version 1. * 19 Feb 1996 Index version 2. Character Set (as defined in the * BDF file) and encoding value added. (WL) * 14 Mar 1996 bug fix: ENCODING property must be used instead of * STARTCHAR. (WL) */ /* This file is part of VFlib * * Copyright (C) 1995 Hirotsugu KAKUGAWA. All rights reserved. * * VFlib is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY. No author or distributor accepts responsibility * to anyone for the consequences of using it or for whether it serves any * particular purpose or works at all, unless he says so in writing. Refer * to the GNU General Public License for full details. * * Everyone is granted permission to copy, modify and redistribute * VFlib, but only under the conditions described in the GNU * General Public License. A copy of this license is supposed to have been * given to you along with VFlib so you can know your rights and * responsibilities. It should be in a file named COPYING. Among other * things, the copyright notice and this notice must be preserved on all * copies. */ #include #include #include #include "VFenc.h" #include "bdf.h" #ifndef SEEK_SET # define SEEK_SET 0 #endif struct s_ch_table { int ccode; /* char code */ long f_pos; /* file position */ }; typedef struct s_ch_table bdf_char_table; struct s_bdf { int bdf_enc; int bdf_chset; int bdf_width; int bdf_height; bdf_char_table *bdf_chars; int bdf_nchar; }; typedef struct s_bdf bdf; bdf *bdf_table = NULL; char *user_enc = NULL; char *user_chset = NULL; int Usage(); int ReadBDF(); int MakeBDFIndex(); int BDF_ReadProp(); int BDF_CountChars(); int BDF_ReadIndex(); int _BDF_ReadIndex(); int BDF_SortIndex(); int BDF_Partition(); int BDF_GetEnc(); int WriteIndex(); int main(argc, argv) int argc; char **argv; { char *fname, *bdf_name, *idx_name; FILE *ifp; FILE *ofp; if (argc < 2) Usage(); fname = argv[1]; if (argc >= 3) user_enc = argv[2]; if (argc == 4) user_chset = argv[3]; if ((bdf_name = malloc(strlen(fname)+strlen(BDF_SUFFIX)+1)) == NULL){ fprintf(stderr, "No memory\n"); exit(1); } if ((idx_name = malloc(strlen(fname)+strlen(IDX_SUFFIX)+1)) == NULL){ fprintf(stderr, "No memory\n"); exit(1); } strcpy(bdf_name, fname); strcat(bdf_name, BDF_SUFFIX); if ((ifp = fopen(bdf_name, "r")) == NULL){ fprintf(stderr, "Cannot open %s\n", bdf_name); exit(1); } strcpy(idx_name, fname); strcat(idx_name, IDX_SUFFIX); if ((ofp = fopen(idx_name, "w")) == NULL){ fprintf(stderr, "Cannot open %s\n", idx_name); exit(1); } (void) ReadBDF(ifp); (void) WriteIndex(ofp); return 0; } int Usage() { fprintf(stderr, "Usage: bdfindex bdf-file [encoding [charset]]\n"); fprintf(stderr, " Index file of `bdf-file'.bdf is generated %s", "as `bdf-file'.bdx\n"); fprintf(stderr, " (`bdf-file' should not contain .bdf extension.)\n"); fprintf(stderr, " Use `encoding' string to force a certain encoding.\n"); fprintf(stderr, " Use `charset' string to force %s", "a certain character set.\n"); fprintf(stderr, "Examples: bdfindex jiskan16\n"); exit(1); } int ReadBDF(fp) FILE *fp; { if ((bdf_table = (bdf*)malloc(sizeof(bdf))) == NULL) goto Err3; bdf_table->bdf_width = 0; bdf_table->bdf_height = 0; if (BDF_ReadProp(fp) < 0) goto Err2; bdf_table->bdf_nchar = BDF_CountChars(fp); if (bdf_table->bdf_nchar < 0) goto Err2; bdf_table->bdf_chars = (bdf_char_table*) calloc(bdf_table->bdf_nchar, sizeof(bdf_char_table)); if (bdf_table->bdf_chars == NULL) goto Err2; if (BDF_ReadIndex(fp) < 0) goto Err1; return 0; Err1: free(bdf_table->bdf_chars); Err2: bdf_table = NULL; Err3: exit(1); } int BDF_ReadProp(fp) FILE *fp; { int found; char buf[160]; char prop_name[160]; char prop_string[160]; char *p; int s_len; int prop_val; if (bdf_table == NULL){ printf("bdfindex: BDF_ReadProp - ILL ARG\n"); return -1; } found = 0; for (;;){ if (fgets(buf, sizeof(buf), fp) == NULL) break; if (strncmp(buf, "ENDPROPERTIES", 13) == 0) break; if (strncmp(buf, "PIXEL_SIZE", 10) == 0){ sscanf(buf, "%s %d", prop_name, &prop_val); found = 1; bdf_table->bdf_width = prop_val; bdf_table->bdf_height = prop_val; continue; } /* we do not consider spaces in the charset registry string */ p = prop_string; if (strncmp(buf, "CHARSET_REGISTRY", 16) == 0){ if (user_chset == NULL){ sscanf(buf, "%s %s", prop_name, p); /* remove the leading and trailing `"' */ p++; s_len = strlen(p); p[s_len - 1] = '\0'; if ((bdf_table->bdf_chset = VFE_SearchCharSet(p)) < 0){ printf("bdfindex: BDF_ReadProp - ILL CHAR SET\n"); return -1; } } continue; } } if (user_chset){ if ((bdf_table->bdf_chset = VFE_SearchCharSet(user_chset)) < 0){ printf("bdfindex: illegal char set parameter on command line.\n"); return -1; } } if (user_enc){ if ((bdf_table->bdf_enc = VFE_SearchEncoding(user_enc)) < 0){ printf("bdfindex: illegal encoding parameter on command line.\n"); return -1; } } else bdf_table->bdf_enc = BDF_GetEnc(bdf_table->bdf_chset); if (found == 0) return -1; return 0; } int BDF_CountChars(fp) FILE *fp; { return _BDF_ReadIndex(fp, 1); } int BDF_ReadIndex(fp) FILE *fp; { return _BDF_ReadIndex(fp, 0); } int _BDF_ReadIndex(fp, count_only) FILE *fp; int count_only; { int ch_code, ch_index, last_ch, need_sorting; char buf[160]; char prop_name[160]; if (bdf_table == NULL){ printf("bdfindex: BDF_ReadIndex - ILL ARG\n"); return -1; } fseek(fp, 0, SEEK_SET); ch_index = 0; last_ch = 0; need_sorting = 0; for (;;){ if (fgets(buf, sizeof(buf), fp) == NULL) break; if (strncmp(buf, "ENDFONT", 7) == 0) break; if (strncmp(buf, "ENCODING", 8) == 0){ /**sscanf(buf, "%s %i", prop_name, &ch_code);**/ sscanf(buf, "%s %d", prop_name, &ch_code); if (last_ch > ch_code) need_sorting = 1; /* Must sort for binary search in VF_Bdf.c */ for (;;){ if (fgets(buf, sizeof(buf), fp) == NULL) goto End; if (strncmp(buf, "ENDCHAR", 7) == 0) break; if (strncmp(buf, "BITMAP", 6) == 0){ if (count_only == 0){ bdf_table->bdf_chars[ch_index].f_pos = (long) ftell(fp); bdf_table->bdf_chars[ch_index].ccode = ch_code; /*printf("%04d: %ld\n", ch_code, bdf_table->bdf_chars[ch_index].f_pos);*/ } last_ch = ch_code; ch_index++; } } } } End: /*printf("XXX nchar = %d\n", ch_index);*/ /*XXX*/ if ((count_only == 0) && (need_sorting == 1)){ /* Must sort the index table for binary search in VF_Bdf.c */ BDF_SortIndex(bdf_table->bdf_chars, 0, ch_index-1); } return ch_index; } int BDF_SortIndex(bdfchp, x, y) bdf_char_table *bdfchp; int x, y; { int z; if (x < y){ z = BDF_Partition(bdfchp, x, y); (void) BDF_SortIndex(bdfchp, x, z-1); (void) BDF_SortIndex(bdfchp, z+1, y); } return 0; } int BDF_Partition(bdfchp, x, y) bdf_char_table *bdfchp; int x, y; { int t, i, p, itmp; long ltmp; t = bdfchp[x].ccode; i = x+1; p = x; for (;;){ if (y < i){ return p; } else if (bdfchp[i].ccode < t){ itmp = bdfchp[i].ccode; ltmp = bdfchp[i].f_pos; bdfchp[i].ccode = bdfchp[p+1].ccode; bdfchp[i].f_pos = bdfchp[p+1].f_pos; bdfchp[p+1].ccode = itmp; bdfchp[p+1].f_pos = ltmp; i++; p++; } else { i++; } } } int BDF_GetEnc(entry) int entry; { int i; for (i = 0; ChSetTable[i].CharSetValue != entry; i++) ; return ChSetTable[i].DefEncValue; } int WriteIndex(fp) FILE *fp; { int i; fprintf(fp, "%d %d %d\n", BDX_VERSION, bdf_table->bdf_chset, bdf_table->bdf_enc); fprintf(fp, "%d %d\n", bdf_table->bdf_width, bdf_table->bdf_height); fprintf(fp, "%d\n", bdf_table->bdf_nchar); i = 0; while (i < bdf_table->bdf_nchar){ fprintf(fp, "%04x %lx\n", bdf_table->bdf_chars[i].ccode, bdf_table->bdf_chars[i].f_pos); i++; } return 0; }