src/hbf.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. HBF_Init
  2. HBF_Open
  3. hbf_load_hbf_file
  4. hbf_release
  5. HBF_Close
  6. HBF_GetBitmap
  7. hbf_find_bitmap
  8. hbf_load_bitmap
  9. hbf_subindex
  10. HBF_GetProp
  11. HBF_GetHBFChar

   1 /*
   2  * hbf.c - a low lebel interface for HBF format fonts
   3  * by Hirotsugu Kakugawa
   4  *
   5  * 26 Mar 1997  Fixed bugs.
   6  * 26 Jan 1998  VFlib 3.4  Changed API.
   7  * 21 Apr 1998  Deleted multiple file extension feature.
   8  * 17 Jun 1998  Support for 'font-directory' capability in font definition. 
   9  */
  10 /*
  11  * Copyright (C) 1996-1998  Hirotsugu Kakugawa. 
  12  * All rights reserved.
  13  *
  14  * This file is part of the VFlib Library.  This library is free
  15  * software; you can redistribute it and/or modify it under the terms of
  16  * the GNU Library General Public License as published by the Free
  17  * Software Foundation; either version 2 of the License, or (at your
  18  * option) any later version.  This library is distributed in the hope
  19  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  20  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  21  * PURPOSE.  See the GNU Library General Public License for more details.
  22  * You should have received a copy of the GNU Library General Public
  23  * License along with this library; if not, write to the Free Software
  24  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  25  */
  26 
  27 
  28 
  29 Private VF_TABLE  hbf_table       = NULL;
  30 
  31 
  32 Private int
  33 HBF_Init(void)
     /* [<][>][^][v][top][bottom][index][help] */
  34 {
  35   HBF_GetHBF(-1);
  36 
  37   if ((hbf_table = vf_table_create()) == NULL){
  38     vf_error = VF_ERR_NO_MEMORY;
  39     return -1;
  40   }
  41 
  42   return 0;
  43 }
  44 
  45 
  46 Private int  hbf_load_hbf_file(HBF, SEXP);
  47 Private int  hbf_load_bitmap(HBF,int);
  48 Private void hbf_release(HBF);
  49 Private int  hbf_subindex(HBF,long,long);
  50 Private unsigned char* hbf_find_bitmap(HBF,long);
  51 
  52 Private int
  53 HBF_Open(char *font_file, SEXP fontdirs)
     /* [<][>][^][v][top][bottom][index][help] */
  54 {
  55   char   *path_name, *uncomp_prog;
  56   int     hbf_id;
  57   HBF     hbf;
  58 
  59   path_name = vf_search_file(font_file, -1, NULL, FALSE, -1, fontdirs, 
  60                              default_compressed_ext, &uncomp_prog);
  61   if (path_name == NULL){
  62     vf_error = VF_ERR_NO_FONT_FILE;
  63     return -1;
  64   }
  65 #if 0
  66   printf("** HBF Font File: %s ==> %s\n", font_file, path_name);
  67 #endif
  68 
  69   if ((hbf_id = (hbf_table->get_id_by_key)(hbf_table, path_name, 
  70                                            strlen(path_name)+1)) >= 0){
  71     (hbf_table->link_by_id)(hbf_table, hbf_id);
  72     return hbf_id;
  73   }
  74 
  75   ALLOC_IF_ERR(hbf, struct s_hbf){
  76     vf_error = VF_ERR_NO_MEMORY;
  77     return -1;
  78   }
  79 
  80   hbf->nchars     = 0;
  81   hbf->point_size = -1;
  82   hbf->pixel_size = -1;
  83   hbf->size       = -1;
  84   hbf->dpi_x      = -1;
  85   hbf->dpi_y      = -1;
  86   hbf->slant      = 0;
  87   hbf->ascent     = 0;
  88   hbf->descent    = 0;
  89   hbf->font_bbx_width  = 0;
  90   hbf->font_bbx_height = 0; 
  91   hbf->font_bbx_xoff   = 0;
  92   hbf->font_bbx_yoff   = 0;
  93   hbf->path_name  = NULL;
  94   hbf->props      = NULL;
  95   hbf->uncompress = NULL;
  96 
  97   if ((hbf->path_name = vf_strdup(path_name)) == NULL){
  98     vf_error = VF_ERR_NO_MEMORY;
  99     goto Error;
 100   }
 101   if ((uncomp_prog != NULL) &&
 102       ((hbf->uncompress = vf_strdup(uncomp_prog)) == NULL)){
 103     vf_error = VF_ERR_NO_MEMORY;
 104     goto Error;
 105   }
 106   if ((hbf->props = vf_sexp_empty_list()) == NULL){
 107     vf_error = VF_ERR_NO_MEMORY;
 108     goto Error;
 109   }
 110 
 111   if (hbf_load_hbf_file(hbf, fontdirs) < 0)
 112     goto Error;
 113 
 114 #if 0
 115   printf("** HBF: charset:%d, %fpt, %fdpi(x) %fdpi(y) (%d chars)\n", 
 116          hbf->charset, hbf->point_size, hbf->dpi_x, hbf->dpi_y, hbf->nchars);
 117 #endif
 118 
 119   if ((hbf_id = (hbf_table->put)(hbf_table, hbf, 
 120                                  path_name, strlen(path_name)+1)) < 0){
 121     vf_error = VF_ERR_NO_MEMORY;
 122     goto Error;
 123   }
 124 
 125   HBF_SetHBF(hbf_id, hbf);
 126 
 127   return hbf_id;
 128 
 129 Error:
 130   hbf_release(hbf);
 131   return -1;
 132 }
 133 
 134 Private int
 135 hbf_load_hbf_file(HBF hbf, SEXP fontdirs)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137   FILE   *fp;
 138   char   linebuf[160], prop_string[160], *name, *file_path, *p;
 139   char   charset_name[80], charset_name2[80], charset_enc2[5], charset[90];
 140   char   *uncomp_prog;
 141   int    index, r, i, n;
 142 
 143   hbf->byte2_range_start = NULL;
 144   hbf->byte2_range_end = NULL;
 145   hbf->byte2_ranges = 0;
 146   hbf->code_range_start = NULL;
 147   hbf->code_range_end = NULL;
 148   hbf->code_range_offset = NULL;
 149   hbf->code_range_bitmap_file_paths = NULL;
 150   hbf->code_range_bitmaps = NULL;
 151   hbf->code_range_offset = NULL;
 152   hbf->code_range_bitmap_uncompresser = NULL;
 153 
 154   if (hbf->uncompress == NULL){
 155     if ((fp = vf_fm_OpenTextFileStream(hbf->path_name)) == NULL){
 156       vf_error = VF_ERR_NO_FONT_FILE;
 157       return -1;
 158     } 
 159   } else {
 160     if ((fp = vf_open_uncompress_stream(hbf->path_name, 
 161                                         hbf->uncompress)) == NULL){
 162       vf_error = VF_ERR_UNCOMPRESS;
 163       return -1;
 164     } 
 165   }
 166 
 167   /* Perse: Char set, pixel size, ... */
 168   strcpy(charset_name, "");
 169   strcpy(charset_name2, "");
 170   strcpy(charset_enc2,  "");
 171   for (;;){
 172     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 173       vf_error = VF_ERR_ILL_FONT_FILE;
 174       goto Unexpected_Error;
 175     }
 176     if (STRCMP(linebuf, "HBF_STARTFONT") == 0)
 177       continue;
 178     if (STRCMP(linebuf, "COMMENT") == 0)
 179       continue;
 180     if (STRCMP(linebuf, "ENDPROPERTIES") == 0)
 181       break;
 182 
 183     { int  x;
 184       for (x = strlen(linebuf)-1; x >= 0; x--){
 185         switch (linebuf[x]){
 186         case '\n':
 187         case '\r':
 188           linebuf[x] = '\0';
 189         }
 190       }
 191     }
 192 
 193     { char  *prop_name, *prop_value, *p, *p0, c0;
 194 
 195       prop_name = linebuf;
 196       for (p = linebuf; (c0 = *p) != '\0'; p++)
 197         if (isspace((int)c0))
 198           break;
 199       p0 = p;
 200       *p = '\0';
 201       if (c0 != '\0'){
 202         p++;
 203         while (isspace((int)*p))
 204           p++;
 205       }
 206       if (*p == '\0'){
 207         prop_value = NULL;
 208       } else {
 209         prop_value = p;
 210         if (prop_value[0] == '"'){
 211           prop_value = &prop_value[1];
 212           prop_value[strlen(prop_value)-1] = '\0';
 213         }
 214         hbf->props = vf_sexp_alist_put(prop_name, prop_value, hbf->props);
 215         if (hbf_debug('P'))
 216           printf("HBF Prop \"%s\" = \"%s\"\n", prop_name, prop_value);
 217       }
 218       *p0 = c0;
 219     }
 220 
 221     if (STRCMP(linebuf, "SIZE") == 0){
 222       sscanf(linebuf, "%*s%lf%lf%lf",
 223              &hbf->point_size, &hbf->dpi_x, &hbf->dpi_y);
 224       hbf->size = hbf->point_size;
 225     } else if ((STRCMP(linebuf, "HBF_BITMAP_BOUNDING_BOX") == 0)
 226                || (STRCMP(linebuf, "FONTBOUNDINGBOX") == 0)){
 227       sscanf(linebuf, "%*s%d%d%d%d", 
 228              &hbf->font_bbx_width, &hbf->font_bbx_height, 
 229              &hbf->font_bbx_xoff, &hbf->font_bbx_yoff);
 230       hbf->ascent = hbf->font_bbx_height + hbf->font_bbx_yoff;
 231       hbf->descent = -hbf->font_bbx_yoff;
 232     } else if (STRCMP(linebuf, "HBF_CODE_SCHEME") == 0){
 233       p = &linebuf[strlen("HBF_CODE_SCHEME")];
 234       while (isspace((int)*p))
 235         p++;
 236       for (i = 0;  p[i] != '\0'; i++)
 237         if (!isprint((int)p[i]))
 238           break;
 239       p[i] = '\0';
 240       strcpy(charset_name, p);
 241     } else if (STRCMP(linebuf, "CHARSET_REGISTRY") == 0){
 242       sscanf(linebuf, "%*s%s", prop_string);
 243       name = &prop_string[1];          /* ignore `"' */
 244       name[strlen(name)-1] = '\0';
 245       strncpy(charset_name2, name, sizeof(charset_name));
 246     } else if (STRCMP(linebuf, "CHARSET_ENCODING") == 0){
 247       sscanf(linebuf, "%*s%s", prop_string);
 248       name = &prop_string[1];          /* ignore `"' */
 249       name[strlen(name)-1] = '\0';
 250       strncpy(charset_enc2, name, sizeof(charset_enc2));
 251     } else if (STRCMP(linebuf, "RESOLUTION_X") == 0){
 252       sscanf(linebuf, "%*s%lf", &hbf->dpi_x);
 253     } else if (STRCMP(linebuf, "RESOLUTION_Y") == 0){
 254       sscanf(linebuf, "%*s%lf", &hbf->dpi_y);
 255     } else if (STRCMP(linebuf, "PIXEL_SIZE") == 0){
 256       sscanf(linebuf, "%*s%d", &hbf->pixel_size);
 257     } else if (STRCMP(linebuf, "POINT_SIZE") == 0){
 258       sscanf(linebuf, "%*s%lf", &hbf->point_size);
 259       hbf->point_size = hbf->point_size / 10.0;
 260     } else if (STRCMP(linebuf, "SLANT") == 0){
 261       sscanf(linebuf, "%*s%s", prop_string);
 262       name = &prop_string[1];          /* ignore `"' */
 263       name[strlen(name)-1] = '\0';
 264       for (p = name; *p != '\0'; p++)
 265         *p = toupper(*p);
 266       hbf->slant = 0.0;
 267       if ((strcmp(name, "I") == 0) || (strcmp(name, "O") == 0)){
 268         hbf->slant = 0.17;
 269       } else if ((strcmp(name, "RI") == 0) || (strcmp(name, "RO") == 0)){
 270         hbf->slant = -0.17;
 271       }
 272     }
 273   }
 274   if (strcmp(charset_name, "") != 0){
 275     sprintf(charset, "%s", charset_name); 
 276   } else {
 277     if ((strcmp(charset_enc2, "") != 0) && ((strcmp(charset_enc2, "0") != 0)))
 278       sprintf(charset, "%s-%s", charset_name2, charset_enc2); 
 279     else
 280       sprintf(charset, "%s", charset_name2); 
 281   }
 282 #if 0
 283   printf("** HBF font file charset (ID=%d) '%s'\n", hbf->charset, charset);
 284   printf("*1 %f %f %f\n",
 285          hbf->point_size, hbf->dpi_x, hbf->dpi_y);
 286   printf("*2 %d %d %d %d\n",
 287          hbf->font_bbx_width, hbf->font_bbx_height,
 288          hbf->font_bbx_xoff, hbf->font_bbx_yoff);
 289 #endif
 290 
 291   if (hbf->point_size < 0)
 292     hbf->point_size = DEFAULT_POINT_SIZE;
 293   if (hbf->pixel_size < 0)
 294     hbf->pixel_size = DEFAULT_PIXEL_SIZE;
 295   if (hbf->dpi_x < 0)
 296     hbf->dpi_x = DEFAULT_DPI;
 297   if (hbf->dpi_y < 0)
 298     hbf->dpi_y = DEFAULT_DPI;
 299 
 300   /* parse: CHARS */
 301   for (;;){
 302     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 303       vf_error = VF_ERR_ILL_FONT_FILE;
 304       goto Unexpected_Error;
 305     }
 306     if (STRCMP(linebuf, "CHARS") == 0){
 307       sscanf(linebuf, "%*s%d", &hbf->nchars);
 308       if (hbf->nchars < 0){
 309         vf_error = VF_ERR_ILL_FONT_FILE;
 310         goto Unexpected_Error;
 311       }
 312       break;
 313     }
 314   }
 315 
 316   /* Parse:  HBF_START_BYTE_2_RANES ... HBF_END_BYTE_2_RANES */
 317   hbf->byte2_ranges = 0;
 318   for (;;){
 319     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 320       vf_error = VF_ERR_ILL_FONT_FILE;
 321       goto Unexpected_Error;
 322     }
 323     if (STRCMP(linebuf, "HBF_START_BYTE_2_RANGES") == 0){
 324       sscanf(linebuf, "%*s%d", &hbf->byte2_ranges);
 325       if (hbf->byte2_ranges <= 0){
 326         vf_error = VF_ERR_ILL_FONT_FILE;
 327         goto Unexpected_Error;
 328       }
 329       ALLOCN_IF_ERR(hbf->byte2_range_start, int, hbf->byte2_ranges){
 330         vf_error = VF_ERR_NO_MEMORY;
 331         goto Unexpected_Error;
 332       }
 333       ALLOCN_IF_ERR(hbf->byte2_range_end, int, hbf->byte2_ranges){
 334         vf_error = VF_ERR_NO_MEMORY;
 335         goto Unexpected_Error;
 336       }
 337       break;
 338     } 
 339   }
 340   hbf->n_byte2 = 0;
 341   for (r = 0; r < hbf->byte2_ranges; r++){
 342     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 343       vf_error = VF_ERR_ILL_FONT_FILE;
 344       goto Unexpected_Error;
 345     }
 346     if (STRCMP(linebuf, "HBF_END_BYTE_2_RANGES") == 0){
 347       vf_error = VF_ERR_ILL_FONT_FILE;
 348       goto Unexpected_Error;
 349     } else if (STRCMP(linebuf, "HBF_BYTE_2_RANGE") == 0){
 350       sscanf(linebuf, "%*s%i-%i",
 351              &(hbf->byte2_range_start[r]), 
 352              &(hbf->byte2_range_end[r]));
 353       hbf->n_byte2 
 354         += (hbf->byte2_range_end[r] - hbf->byte2_range_start[r] + 1);
 355     } 
 356   }
 357 
 358   for (i = 0; i < 256; i++)
 359     hbf->byte2_index[i] = -1;
 360   index = 0;
 361   for (r = 0; r < hbf->byte2_ranges; r++){
 362     for (i = hbf->byte2_range_start[r]; i <= hbf->byte2_range_end[r]; i++)
 363       hbf->byte2_index[i] = index++;
 364   }
 365 
 366   /* Parse:  HBF_START_CODE_RANES ... HBF_END_CODE_RANES */
 367   for (;;){
 368     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 369       vf_error = VF_ERR_ILL_FONT_FILE;
 370       goto Unexpected_Error;
 371     }
 372     if (STRCMP(linebuf, "HBF_START_CODE_RANGES") == 0){
 373       sscanf(linebuf, "%*s%d", &hbf->code_ranges);
 374       if (hbf->code_ranges <= 0){
 375         vf_error = VF_ERR_ILL_FONT_FILE;
 376         goto Unexpected_Error;
 377       }
 378       ALLOCN_IF_ERR(hbf->code_range_start, long, hbf->code_ranges){
 379         vf_error = VF_ERR_NO_MEMORY;
 380         goto Unexpected_Error;
 381       }
 382       ALLOCN_IF_ERR(hbf->code_range_end, long, hbf->code_ranges){
 383         vf_error = VF_ERR_NO_MEMORY;
 384         goto Unexpected_Error;
 385       }
 386       ALLOCN_IF_ERR(hbf->code_range_bitmaps, 
 387                     unsigned char**, hbf->code_ranges){
 388         vf_error = VF_ERR_NO_MEMORY;
 389         goto Unexpected_Error;
 390       }
 391       ALLOCN_IF_ERR(hbf->code_range_offset, long, hbf->code_ranges){
 392         vf_error = VF_ERR_NO_MEMORY;
 393         goto Unexpected_Error;
 394       }
 395       ALLOCN_IF_ERR(hbf->code_range_bitmap_file_paths, 
 396                     char*, hbf->code_ranges){
 397         vf_error = VF_ERR_NO_MEMORY;
 398         goto Unexpected_Error;
 399       }
 400       ALLOCN_IF_ERR(hbf->code_range_bitmap_uncompresser, 
 401                     char*, hbf->code_ranges){
 402         vf_error = VF_ERR_NO_MEMORY;
 403         goto Unexpected_Error;
 404       }
 405       break;
 406     } 
 407   }
 408 
 409   for (r = 0; r < hbf->code_ranges; ){
 410     if (fgets(linebuf, sizeof(linebuf), fp) == NULL){
 411       vf_error = VF_ERR_ILL_FONT_FILE;
 412       goto Unexpected_Error;
 413     }
 414     if (STRCMP(linebuf, "HBF_END_CODE_RANGES") == 0){
 415       vf_error = VF_ERR_ILL_FONT_FILE;
 416       goto Unexpected_Error;
 417     } else if (STRCMP(linebuf, "HBF_CODE_RANGE") == 0){
 418       sscanf(linebuf, "%*s%li-%li%s%li",
 419              &(hbf->code_range_start[r]),
 420              &(hbf->code_range_end[r]),
 421              prop_string,
 422              &(hbf->code_range_offset[r]));
 423 #if 0
 424       printf(">>%s", linebuf);
 425       printf("   %lx -- %lx,  %s,  %ld\n", 
 426              hbf->code_range_start[r], hbf->code_range_end[r],
 427              prop_string, hbf->code_range_offset[r]);
 428 #endif
 429       file_path = NULL;
 430       if (fontdirs != NULL){
 431         file_path 
 432           = vf_search_file(prop_string, -1, NULL, FALSE, -1, fontdirs, 
 433                            default_compressed_ext, &uncomp_prog);
 434       }
 435       if (file_path == NULL){
 436         vf_error = VF_ERR_NO_FONT_FILE;
 437         goto Unexpected_Error;
 438       }
 439       if ((hbf->code_range_bitmap_file_paths[r] 
 440            = vf_strdup(file_path)) == NULL){
 441         vf_error = VF_ERR_NO_MEMORY;
 442         goto Unexpected_Error;
 443       } 
 444 #if 0
 445       printf("** HBF Bitmap File: %s\n", hbf->code_range_bitmap_file_paths[r]);
 446 #endif
 447       n = hbf_subindex(hbf, hbf->code_range_end[r], 
 448                        hbf->code_range_start[r]) + 1;
 449       ALLOCN_IF_ERR(hbf->code_range_bitmaps[r], unsigned char*, n){
 450         vf_error = VF_ERR_NO_MEMORY;
 451         goto Unexpected_Error;
 452       }
 453       for (i = 0; i < n; i++)
 454         hbf->code_range_bitmaps[r][i] = NULL;
 455 
 456       if (uncomp_prog == NULL){
 457         hbf->code_range_bitmap_uncompresser[r] = NULL;
 458       } else {
 459         if ((hbf->code_range_bitmap_uncompresser[r] 
 460              = vf_strdup(uncomp_prog)) == NULL){
 461           vf_error = VF_ERR_NO_MEMORY;
 462           goto Unexpected_Error;
 463         }
 464         if (hbf_load_bitmap(hbf, r) < 0){
 465           vf_error = VF_ERR_ILL_FONT_FILE;
 466           goto Unexpected_Error;
 467         }
 468       }
 469 
 470       r++;
 471     } 
 472   }
 473 
 474   if ((uncomp_prog != NULL) && (fp != NULL))
 475     vf_close_uncompress_stream(fp);
 476   return 0; 
 477 
 478 Unexpected_Error:
 479   if (uncomp_prog != NULL)
 480     vf_close_uncompress_stream(fp);
 481   hbf_release(hbf);
 482   return -1;
 483 }
 484 
 485 
 486 Private void
 487 hbf_release(HBF hbf)
     /* [<][>][^][v][top][bottom][index][help] */
 488 {
 489   int  i, n, r;
 490 
 491   if (hbf != NULL){
 492     vf_free(hbf->path_name);
 493     vf_free(hbf->uncompress);
 494     vf_free(hbf->byte2_range_start);
 495     vf_free(hbf->byte2_range_end);
 496     vf_free(hbf->code_range_start);
 497     vf_free(hbf->code_range_end);
 498     if (hbf->code_range_bitmap_file_paths != NULL)
 499       for (r = 0; r < hbf->byte2_ranges; r++)
 500         vf_free(hbf->code_range_bitmap_file_paths[r]);
 501     vf_free(hbf->code_range_bitmap_file_paths);
 502     if (hbf->code_range_bitmap_uncompresser != NULL)
 503       for (r = 0; r < hbf->byte2_ranges; r++)
 504         vf_free(hbf->code_range_bitmap_uncompresser[r]);
 505     vf_free(hbf->code_range_bitmap_uncompresser);
 506     if (hbf->code_range_bitmaps != NULL){
 507       for (r = 0; r < hbf->byte2_ranges; r++){
 508         if (hbf->code_range_bitmaps[r] == NULL)
 509           continue;
 510         n = hbf_subindex(hbf, hbf->code_range_end[r], hbf->code_range_end[r]);
 511         for (i = 0; i <= n; i++)
 512           vf_free(hbf->code_range_bitmaps[r][i]);
 513         vf_free(hbf->code_range_bitmaps[r]);
 514       }
 515     }
 516     vf_free(hbf->code_range_offset);
 517     vf_sexp_free(&hbf->props);
 518     vf_free(hbf);
 519   }
 520 }
 521 
 522 Private void
 523 HBF_Close(int hbf_id)
     /* [<][>][^][v][top][bottom][index][help] */
 524 {
 525   HBF  hbf;
 526 
 527   if ((hbf = HBF_GetHBF(hbf_id)) == NULL){
 528     fprintf(stderr, "VFlib Internal error: HBF_Close()\n");
 529     abort();
 530   }
 531 
 532   if ((hbf_table->unlink_by_id)(hbf_table, hbf_id) <= 0)
 533     hbf_release(hbf);
 534 }
 535 
 536 
 537 Private HBF_CHAR
 538 HBF_GetBitmap(int hbf_id, long code_point)
     /* [<][>][^][v][top][bottom][index][help] */
 539 {
 540   HBF         hbf;
 541 
 542   hbf = HBF_GetHBF(hbf_id);
 543   return HBF_GetHBFChar(hbf, code_point);
 544 }
 545 
 546 Private unsigned char*
 547 hbf_find_bitmap(HBF hbf, long code_point)
     /* [<][>][^][v][top][bottom][index][help] */
 548 {
 549   int            subindex, bmsize, r, i;
 550   long           offset;
 551   FILE           *fp;
 552   unsigned char  *p;
 553 
 554   subindex = 0;
 555   for (r = 0; r < hbf->code_ranges; r++){
 556     if ((hbf->code_range_start[r] <= code_point) 
 557         && (code_point <= hbf->code_range_end[r])){
 558       break;
 559     }
 560   }
 561   if (r == hbf->code_ranges){
 562     vf_error = VF_ERR_ILL_CODE_POINT;
 563     return NULL;
 564   }
 565 
 566   if ((subindex = hbf_subindex(hbf, code_point,
 567                                hbf->code_range_start[r])) < 0){
 568     vf_error = VF_ERR_ILL_CODE_POINT;
 569     return NULL;
 570   }
 571   if (hbf->code_range_bitmaps[r][subindex] != NULL)
 572     return hbf->code_range_bitmaps[r][subindex];
 573 
 574 #if 0
 575   printf("  Opening bitmap file: %s\n", 
 576          hbf->code_range_bitmap_file_paths[r]);
 577 #endif
 578   if (hbf->code_range_bitmap_uncompresser[r] != NULL){
 579     fprintf(stderr, "VFlib Internal error: HBF_GetBitmap()\n");
 580     abort();
 581   }
 582 
 583   if ((fp = vf_fm_OpenBinaryFileStream(hbf->code_range_bitmap_file_paths[r])) 
 584       == NULL){
 585     vf_error = VF_ERR_NO_FONT_FILE;
 586     return NULL;
 587   } 
 588   bmsize = ((hbf->font_bbx_width+7)/8) * hbf->font_bbx_height; 
 589   offset = hbf->code_range_offset[r] + subindex * bmsize;
 590   fseek(fp, offset, SEEK_SET); 
 591 #if 0
 592   printf("  code point: 0x%04x, index: %d, offset: %d\n",
 593          code_point, subindex, offset);
 594 #endif
 595 
 596   ALLOCN_IF_ERR(hbf->code_range_bitmaps[r][subindex], unsigned char, bmsize)
 597     return NULL;
 598   p = &hbf->code_range_bitmaps[r][subindex][0];
 599   for (i = 0; i < bmsize; i++)
 600     *(p++) = getc(fp);
 601 
 602   return hbf->code_range_bitmaps[r][subindex];
 603 }
 604 
 605 Private int
 606 hbf_load_bitmap(HBF hbf, int r)
     /* [<][>][^][v][top][bottom][index][help] */
 607 {
 608   int            bmsize, index, i, j;
 609   unsigned char  *p;
 610   FILE           *fp;
 611 
 612   if (hbf->code_range_bitmap_uncompresser[r] == NULL){
 613     fprintf(stderr, "VFlib fatal: hbf_load_bitmap()\n");
 614     abort();
 615   }
 616 
 617   fp = vf_open_uncompress_stream(hbf->code_range_bitmap_file_paths[r], 
 618                                  hbf->code_range_bitmap_uncompresser[r]);
 619   if (fp == NULL){
 620     vf_error = VF_ERR_UNCOMPRESS;
 621     return -1;
 622   }
 623 
 624   if ((index = hbf_subindex(hbf, hbf->code_range_end[r],
 625                             hbf->code_range_start[r])) < 0){
 626     fprintf(stderr, "VFlib fatal: hbf_load_bitmap()\n");
 627     abort();
 628   }
 629 
 630   fseek(fp, hbf->code_range_offset[r], SEEK_SET);
 631   for (i = 0; i <= index; i++){
 632     bmsize = ((hbf->font_bbx_width+7)/8) * hbf->font_bbx_height; 
 633     ALLOCN_IF_ERR(hbf->code_range_bitmaps[r][i], unsigned char, bmsize)
 634       return -1;
 635     p =  &hbf->code_range_bitmaps[r][i][0];
 636     for (j = 0; j < bmsize; j++)
 637       *(p++) = getc(fp);
 638   }
 639 
 640   vf_close_uncompress_stream(fp);
 641   return 0;
 642 }
 643 
 644 Private int
 645 hbf_subindex(HBF hbf, long code_point, long base)
     /* [<][>][^][v][top][bottom][index][help] */
 646 {
 647   int  code_hi, code_lo, base_hi, base_lo;
 648   int  subindex, r;
 649 
 650   code_hi = code_point / 256;  code_lo = code_point % 256;
 651   base_hi = base / 256;        base_lo = base % 256;
 652 
 653   /**
 654   printf(" code hi:%x lo:%02x,  base hi:%d lo:%d,  %d %d\n",
 655          code_hi, code_lo, base_hi, base_lo, 
 656          hbf->byte2_index[code_lo], hbf->byte2_index[base_lo]);
 657   **/
 658   if (base_hi == code_hi){
 659     if ((hbf->byte2_index[code_lo] < 0) || (hbf->byte2_index[base_lo] < 0))
 660       return -1;
 661     subindex = hbf->byte2_index[code_lo] - hbf->byte2_index[base_lo];
 662   } else {   /* base_hi != code_hi */
 663     /* in base_hi */
 664     subindex = hbf->n_byte2 - hbf->byte2_index[base_lo];
 665     /* in base_hi+1, ..., code_hi-1 */
 666     for (r = base_hi+1; r <= code_hi-1; r++)
 667       subindex += hbf->n_byte2;
 668     /* in code_hi */
 669     subindex += hbf->byte2_index[code_lo];
 670   }
 671 #if 0
 672   printf("hbf_subindex: index:%d, base:0x%lx, code:0x%x\n",
 673     subindex, base, code_point);
 674 #endif
 675   return subindex;
 676 }
 677 
 678 
 679 Private char*
 680 HBF_GetProp(HBF hbf, char *name)
     /* [<][>][^][v][top][bottom][index][help] */
 681 {
 682   SEXP  v;
 683   char  *r;
 684 
 685   if ((v = vf_sexp_assoc(name, hbf->props)) == NULL)
 686     return NULL;
 687   if ((r = vf_strdup(vf_sexp_get_cstring(vf_sexp_cadr(v)))) == NULL){
 688     vf_error = VF_ERR_NO_MEMORY;
 689     return NULL;
 690   }
 691 
 692   return r;     /* CALLER MUST RELEASE THIS STRING LATER */
 693 }
 694 
 695 
 696 Private HBF_CHAR
 697 HBF_GetHBFChar(HBF hbf, long code_point)
     /* [<][>][^][v][top][bottom][index][help] */
 698 {
 699   static struct s_hbf_char  hbf_char;
 700 
 701   hbf_char.bbx_width  = hbf->font_bbx_width;
 702   hbf_char.bbx_height = hbf->font_bbx_height;
 703   hbf_char.off_x = hbf->font_bbx_xoff;
 704   hbf_char.off_y = hbf->font_bbx_yoff;
 705   hbf_char.mv_x = hbf->font_bbx_width;
 706   hbf_char.mv_y = 0;
 707   hbf_char.bitmap = hbf_find_bitmap(hbf, code_point);
 708   hbf_char.raster = (hbf->font_bbx_width+7)/8;
 709   return &hbf_char;
 710 }
 711 
 712 
 713 /*EOF*/

/* [<][>][^][v][top][bottom][index][help] */