src/zeit.c

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

FUNCTIONS

This source file includes following functions.
  1. ZEIT_Init
  2. ZEIT_Open
  3. ZEIT_Close
  4. zeit_release
  5. zeit_make_header
  6. zeit_read_header
  7. zeit_correct_size
  8. ZEIT_ReadOutline
  9. zeit_code2c
  10. zeit_read_1byte
  11. zeit_read_4bytes
  12. zeit_init_bit_stream
  13. zeit_read_10bits
  14. zeit_seek
  15. zeit_current_pos

   1 /*
   2  * zeit.c - 'Syotai Kurabu' font interface
   3  * by Hirotsugu Kakugawa
   4  *
   5  *  3 Dec 1996  First version.
   6  * 10 Dec 1996  Changed for VFlib version 3.1
   7  * 12 Dec 1996  Eliminated "do" capability.
   8  * 26 Feb 1997  Added 'query_font_type'.
   9  *  7 Aug 1997  VFlib 3.3  Changed API.
  10  * 27 Jan 1998  VFlib 3.4  Changed API.
  11  * 18 Oct 2001    Fixed memory leaks.
  12  *
  13  */
  14 /*
  15  * Copyright (C) 1993-2001 Hirotsugu Kakugawa. 
  16  * All rights reserved.
  17  *
  18  * This file is part of the VFlib Library.  This library is free
  19  * software; you can redistribute it and/or modify it under the terms of
  20  * the GNU Library General Public License as published by the Free
  21  * Software Foundation; either version 2 of the License, or (at your
  22  * option) any later version.  This library is distributed in the hope
  23  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  24  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  25  * PURPOSE.  See the GNU Library General Public License for more details.
  26  * You should have received a copy of the GNU Library General Public
  27  * License along with this library; if not, write to the Free Software
  28  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  29  */
  30 
  31 #include  "zeit.h"
  32 
  33 static  VF_TABLE  zeit_table    = NULL;
  34 
  35 
  36 
  37 Private int
  38 ZEIT_Init(void)
     /* [<][>][^][v][top][bottom][index][help] */
  39 {
  40   ZEIT_GetZEIT(-1);
  41 
  42   if ((zeit_table = vf_table_create()) == NULL){
  43     vf_error = VF_ERR_NO_MEMORY;
  44     return -1;
  45   }
  46 
  47   return 0;
  48 }
  49 
  50 
  51 Private void      zeit_release(ZEIT zeit);
  52 Private int       zeit_make_header(char*,int,char**,long**,long**,int);
  53 
  54 
  55 Private int
  56 ZEIT_Open(char *font_name)
     /* [<][>][^][v][top][bottom][index][help] */
  57 {
  58   ZEIT  zeit;
  59   int   zeit_id;
  60 
  61   if ((zeit_id = (zeit_table->get_id_by_key)(zeit_table, font_name, 
  62                                              strlen(font_name)+1)) >= 0){
  63     (zeit_table->link_by_id)(zeit_table, zeit_id);
  64     return zeit_id;
  65   }
  66 
  67   ALLOC_IF_ERR(zeit, struct s_zeit){
  68     vf_error = VF_ERR_NO_MEMORY;
  69     return -1;
  70   }
  71   zeit->path_name1 = NULL;
  72   zeit->ol_size1   = NULL;
  73   zeit->ol_offset1 = NULL;
  74   zeit->path_name2 = NULL;
  75   zeit->ol_size2   = NULL;
  76   zeit->ol_offset2 = NULL;
  77 
  78   if (zeit_make_header(font_name, 1, &zeit->path_name1,
  79                        &zeit->ol_size1, &zeit->ol_offset1, 1) < 0)
  80     goto Error;
  81   if (zeit_make_header(font_name, 2, &zeit->path_name2,
  82                        &zeit->ol_size2, &zeit->ol_offset2, 2) < 0)
  83     goto Error;
  84   
  85   if ((zeit_id = (zeit_table->put)(zeit_table, zeit, 
  86                                    font_name, strlen(font_name)+1)) < 0){
  87     vf_error = VF_ERR_NO_MEMORY;
  88     goto Error;
  89   }
  90 
  91   ZEIT_SetZEIT(zeit_id, zeit);
  92 
  93   return zeit_id;
  94 
  95 Error:
  96   zeit_release(zeit);
  97   return -1;
  98 }
  99 
 100 
 101 Private void
 102 ZEIT_Close(int zeit_id)
     /* [<][>][^][v][top][bottom][index][help] */
 103 {
 104   ZEIT  zeit;
 105 
 106   if ((zeit = ZEIT_GetZEIT(zeit_id)) == NULL){
 107     fprintf(stderr, "VFlib internal error: ZEIT_Close()\n");
 108     vf_error = VF_ERR_INTERNAL;
 109     return;
 110   }
 111   if ((zeit_table->unlink_by_id)(zeit_table, zeit_id) > 0)
 112     return;
 113   zeit_release(zeit);
 114 }
 115 
 116 
 117 Private void
 118 zeit_release(ZEIT zeit)
     /* [<][>][^][v][top][bottom][index][help] */
 119 {
 120   if (zeit != NULL){
 121     vf_free(zeit->path_name1);
 122     vf_free(zeit->path_name2);
 123     vf_free(zeit->ol_offset1);
 124     vf_free(zeit->ol_offset2);
 125     vf_free(zeit->ol_size1);
 126     vf_free(zeit->ol_size2);
 127     vf_free(zeit);
 128   }
 129 }
 130 
 131 
 132 Private int   zeit_read_header(long**,long**,char*);
 133 
 134 Private int            zeit_correct_size(long*,long*,FILE*,int);
 135 Private int            zeit_code2c(int);
 136 Private int            zeit_read_1byte(FILE*);
 137 Private unsigned long  zeit_read_4bytes(FILE*);
 138 Private void           zeit_init_bit_stream(FILE*);
 139 Private int            zeit_read_10bits(void);
 140 Private void           zeit_seek(FILE*,long);
 141 Private long           zeit_current_pos(FILE*);
 142 
 143 
 144 Private int
 145 zeit_make_header(char *font_name, int ext, char **path_namep,
     /* [<][>][^][v][top][bottom][index][help] */
 146                  long **ol_sizep, long **ol_offsetp, int type)
 147 {
 148   char    *e;
 149   char    fname[MAXPATHLEN];
 150   int     i;
 151   SEXP    s;
 152 
 153   *path_namep = NULL;
 154   *ol_offsetp = NULL;
 155   *ol_sizep   = NULL;
 156 
 157   for (s = default_extensions; vf_sexp_consp(s); s = vf_sexp_cdr(s)){
 158     e = vf_sexp_get_cstring(vf_sexp_car(s));
 159     sprintf(fname, "%s%s%d", font_name, e, ext);
 160     if ((*path_namep
 161          = vf_search_file(fname, -1, NULL, FALSE, -1,
 162                           default_fontdirs, NULL, NULL)) != NULL)
 163       break;
 164   }
 165 
 166   if (*path_namep == NULL){
 167     if (type == 1){
 168       vf_error = VF_ERR_NO_FONT_FILE;
 169       return -1;
 170     }
 171     return 0;
 172   }
 173 
 174   if (debug_on('f'))
 175     printf("VFlib ZEIT: font path: %s\n", *path_namep);
 176 
 177   ALLOCN_IF_ERR(*ol_offsetp, long, ZEIT_NCHARS){
 178     vf_error = VF_ERR_NO_MEMORY;
 179     goto Error;
 180   }
 181   ALLOCN_IF_ERR(*ol_sizep, long, ZEIT_NCHARS){
 182     vf_error = VF_ERR_NO_MEMORY;
 183     goto Error;
 184   }
 185 
 186   for (i = 0; i < ZEIT_NCHARS; i++){
 187     (*ol_offsetp)[i] = -1;
 188     (*ol_sizep)[i]   = 0;
 189   }
 190 
 191   if (zeit_read_header(ol_sizep, ol_offsetp, *path_namep) < 0){
 192     goto Error;
 193   }
 194 
 195   return 0;
 196 
 197 Error:
 198   vf_free(*path_namep);  *path_namep = NULL;
 199   vf_free(*ol_offsetp);  *ol_offsetp = NULL;
 200   vf_free(*ol_sizep);    *ol_sizep   = NULL;
 201   return -1;
 202 }
 203 
 204 
 205 Private int 
 206 zeit_read_header(long **ol_sizep, long **ol_offsetp, char *font_path)
     /* [<][>][^][v][top][bottom][index][help] */
 207 {
 208   int    i, j;
 209   FILE   *fp;
 210 
 211   if ((fp = vf_fm_OpenBinaryFileStream(font_path)) == NULL){
 212     fprintf(stderr, "VFlib Error. File not found: %s\n", font_path);
 213     return -1;
 214   }
 215 
 216   (void) zeit_read_1byte(fp);
 217   (void) zeit_read_1byte(fp);
 218 
 219   for (i = 0; i < ZEIT_NCHARS; i++){
 220     (*ol_offsetp)[i] = zeit_read_4bytes(fp);
 221     if (debug_on('i'))
 222       printf("VFlib ZEIT: Header  %04d: %08lx\n", i, (*ol_offsetp)[i]);
 223   }
 224 
 225   for (i = 0; i < ZEIT_NCHARS-1; i++){
 226     if ((*ol_offsetp)[i] == 0xffffffff){
 227       (*ol_sizep)[i] = 0;
 228       continue;
 229     }
 230     for (j = i+1; ; j++){
 231       if (j >= ZEIT_NCHARS){
 232         (*ol_sizep)[i] = -(THRESHOLD_SIZE+1);
 233         break;
 234       }
 235       if ((*ol_offsetp)[j] != 0xffffffff){
 236         (*ol_sizep)[i] = -((*ol_offsetp)[j] - (*ol_offsetp)[i]); /* A MAGIC */
 237         break;
 238       }
 239     }
 240     if (-((*ol_sizep)[i]) > THRESHOLD_SIZE)  /* Large... check size. */
 241       zeit_correct_size(&((*ol_sizep)[i]), &((*ol_offsetp)[i]), fp, i); 
 242   }
 243   if ((*ol_offsetp)[ZEIT_NCHARS-1] == 0xffffffff){
 244     (*ol_sizep)[ZEIT_NCHARS-1] = 0;
 245   } else {
 246     (*ol_sizep)[ZEIT_NCHARS-1] = -(THRESHOLD_SIZE+1);           /* A MAGIC */
 247     zeit_correct_size(&((*ol_sizep)[i]), &((*ol_offsetp)[i]), 
 248                       fp, ZEIT_NCHARS-1);
 249   }
 250 
 251   return 0;
 252 }
 253 
 254 Private int
 255 zeit_correct_size(long *sizep, long *offsetp, FILE *fp, int i)
     /* [<][>][^][v][top][bottom][index][help] */
 256 {
 257   int   x, y;
 258 
 259   if (debug_on('i'))
 260     printf("VFlib ZEIT: Correct Size  %04x:  size %d, offs %ld\n", 
 261            i, (int)-(*sizep), *offsetp);
 262 
 263   zeit_seek(fp, *offsetp);
 264   zeit_init_bit_stream(fp);
 265   for (;;){
 266     x = zeit_read_10bits(); 
 267     y = zeit_read_10bits();
 268     if ((x == 1023) && (y == 1023))
 269       break;
 270     for (;;){
 271       x = zeit_read_10bits();
 272       y = zeit_read_10bits();
 273       if ((x == 1023) && (y == 1023))
 274         break;
 275     }
 276   }
 277   *sizep = -(zeit_current_pos(fp) - *offsetp);
 278 
 279   if (debug_on('i'))
 280     printf("VFlib ZEIT:   ==>  %04x\n", (int)-(*sizep));
 281 
 282   return *sizep;
 283 }
 284 
 285 Private VF_OUTLINE
 286 ZEIT_ReadOutline(int zeit_id, int code_point, 
     /* [<][>][^][v][top][bottom][index][help] */
 287                  double mag_x, double mag_y)
 288 {
 289   FILE       *fp;
 290   ZEIT       zeit;
 291   int        idx, x, y, xx, yy, max_code, space2121;
 292   char       *font_file;
 293   VF_OUTLINE      outline;
 294   VF_OUTLINE_ELEM *sizep;
 295   long          size, offs;
 296   unsigned int  scode;
 297   double        mx, my;
 298 
 299   mx = mag_x;
 300   my = mag_y;
 301   if (mx > 1){
 302     mx = 1.0;
 303     my = 1.0 / mx;
 304   }
 305 
 306   if ((zeit = ZEIT_GetZEIT(zeit_id)) == NULL){
 307     fprintf(stderr, "VFlib internal error: ZEIT_ReadOutline()\n");
 308     vf_error = VF_ERR_INTERNAL;
 309     return NULL;
 310   }
 311   
 312   /* Assume JISX0208-1990 & KUTEN encoding */
 313   max_code = 0x7426;
 314   space2121 = 1;
 315 
 316   if ((code_point < 0x2121) || (max_code < code_point)
 317       || (code_point%256 < 0x21) || (0x7e < code_point%256)){
 318     vf_error = VF_ERR_ILL_CODE_POINT;
 319     return NULL;
 320   }
 321 
 322   if ((space2121 == 1) && (code_point == 0x2121)){
 323     size = VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + 1;
 324     ALLOCN_IF_ERR(outline, VF_OUTLINE_ELEM, size)
 325       return NULL;
 326     outline[VF_OL_HEADER_INDEX_DATA_SIZE] = size;
 327     return outline;
 328   }
 329 
 330   scode = zeit_code2c(code_point);
 331   if (code_point < 0x5000){
 332     font_file = zeit->path_name1;
 333     offs  = zeit->ol_offset1[scode];
 334     sizep = &zeit->ol_size1[scode];
 335   } else {
 336     font_file = zeit->path_name2;
 337     offs  = zeit->ol_offset2[scode];
 338     sizep = &zeit->ol_size2[scode];
 339   }
 340   if (*sizep == 0)
 341     return NULL;
 342   if (*sizep < 0)                 /* A MAGIC */
 343     size = 2*(-*sizep) + 1; 
 344   else
 345     size = *sizep + 1;
 346 
 347   ALLOCN_IF_ERR(outline, VF_OUTLINE_ELEM, 
 348                 VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + size)
 349     return NULL;
 350   
 351   if ((fp = vf_fm_OpenBinaryFileStream(font_file)) == NULL){
 352     fprintf(stderr, "VFlib Error. File not found: %s\n", font_file);
 353     return NULL;
 354   }
 355 
 356   zeit_seek(fp, offs);
 357   zeit_init_bit_stream(fp);
 358   for (idx = 0; ; ){
 359     x = zeit_read_10bits();
 360     y = zeit_read_10bits();
 361     if ((x == 1023) && (y == 1023))
 362       break;
 363     xx = VF_OL_COORD_OFFSET + mx * (x*VF_OL_COORD_RANGE)/ZEIT_MAX_VALUE;
 364     yy = VF_OL_COORD_OFFSET + my * (y*VF_OL_COORD_RANGE)/ZEIT_MAX_VALUE;
 365     outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + idx++] 
 366       = VF_OL_INSTR_TOKEN | VF_OL_INSTR_CWCURV | VF_OL_INSTR_LINE;
 367     outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + idx++] 
 368       = VF_OL_MAKE_XY(xx, yy);
 369     for (;;){
 370       x = zeit_read_10bits();
 371       y = zeit_read_10bits();
 372       if ((x == 1023) && (y == 1023))
 373         break;
 374       xx = VF_OL_COORD_OFFSET + mx * (x*VF_OL_COORD_RANGE)/ZEIT_MAX_VALUE;
 375       yy = VF_OL_COORD_OFFSET + my * (y*VF_OL_COORD_RANGE)/ZEIT_MAX_VALUE;
 376       outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + idx++] = VF_OL_MAKE_XY(xx, yy);
 377     }
 378   }
 379   outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0 + idx++] = 0;
 380 
 381   if (outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0] != 0)
 382     outline[VF_OL_OUTLINE_HEADER_SIZE_TYPE0] |= VF_OL_INSTR_CHAR;
 383 
 384   if (*sizep < 0)
 385     *sizep = (long)idx;
 386 
 387   if (debug_on('i'))
 388     printf("VFlib ZEIT:      SIZE %5ld\n", *sizep);
 389 
 390   outline[VF_OL_HEADER_INDEX_DATA_SIZE] 
 391     = *sizep + VF_OL_OUTLINE_HEADER_SIZE_TYPE0;
 392 
 393   return outline;
 394 }
 395 
 396 
 397 Private int
 398 zeit_code2c(int code)
     /* [<][>][^][v][top][bottom][index][help] */
 399 {
 400   if (code < 0x5000)
 401     return ((code/0x100) - 0x21)*0x5e + (code%0x100) - 0x21;
 402 
 403   return ((code/0x100) - 0x50)*0x5e + (code%0x100) - 0x21;
 404 }
 405 
 406 
 407 
 408 Private int
 409 zeit_read_1byte(FILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
 410 {
 411   return getc(fp);
 412 }
 413 
 414 Private unsigned long
 415 zeit_read_4bytes(FILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
 416 {
 417   unsigned long i1, i2, i3, i4;
 418   
 419   i1 = (unsigned long)zeit_read_1byte(fp);
 420   i2 = (unsigned long)zeit_read_1byte(fp);
 421   i3 = (unsigned long)zeit_read_1byte(fp);
 422   i4 = (unsigned long)zeit_read_1byte(fp);
 423 
 424   return i1 + i2*0x100 + i3*0x10000 + i4*0x1000000;
 425 }
 426 
 427 
 428 Private FILE           *zeit_bitstream_fp = NULL;
 429 Private unsigned int   zeit_left_bits  = 0;
 430 Private unsigned long  zeit_bit_stream = 0;
 431 Private unsigned long  zeit_power2tbl[] = {
 432   0x000001,0x000002,0x000004,0x000008,0x000010,0x000020,0x000040,0x000080,
 433   0x000100,0x000200,0x000400,0x000800,0x001000,0x002000,0x004000,0x008000,
 434   0x010000,0x020000,0x040000,0x080000,0x100000,0x200000,0x400000,0x800000
 435 }; 
 436 
 437 Private void
 438 zeit_init_bit_stream(FILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
 439 {
 440   zeit_bitstream_fp = fp;
 441   zeit_bit_stream   = 0;
 442   zeit_left_bits    = 0;
 443 }
 444 
 445 Private int 
 446 zeit_read_10bits(void)
     /* [<][>][^][v][top][bottom][index][help] */
 447 {
 448   if (zeit_left_bits < 10){
 449     zeit_bit_stream  *= 0x10000;
 450     zeit_bit_stream  += (unsigned int)zeit_read_1byte(zeit_bitstream_fp);
 451     zeit_bit_stream  += (unsigned int)zeit_read_1byte(zeit_bitstream_fp)*0x100;
 452     zeit_left_bits   += 16;
 453   }
 454   zeit_left_bits -= 10;
 455 
 456   return (zeit_bit_stream/zeit_power2tbl[zeit_left_bits]) % ZEIT_MAX_VALUE;
 457 }
 458 
 459 Private void
 460 zeit_seek(FILE *fp, long pos)
     /* [<][>][^][v][top][bottom][index][help] */
 461 {
 462   fseek(fp, pos + ZEIT_HEADER_SIZE, SEEK_SET);
 463 }
 464 
 465 Private long
 466 zeit_current_pos(FILE *fp)
     /* [<][>][^][v][top][bottom][index][help] */
 467 {
 468   return ftell(fp) - ZEIT_HEADER_SIZE;
 469 }
 470 
 471 
 472 /*EOF*/

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