src/gf.c

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

FUNCTIONS

This source file includes following functions.
  1. GF_CacheLoader
  2. GF_CacheDisposer
  3. gf_loader
  4. gf_read_glyph

   1 /*
   2  * gf.c - TeX GF format font fonts loader.
   3  *
   4  * 28 Sep 1996  First version.
   5  * 30 Jan 1998  VFlib 3.4  Changed API.
   6  * 16 Sep 1999  Changed not to use TFM
   7  */
   8 /*
   9  * Copyright (C) 1996-1999  Hirotsugu Kakugawa. 
  10  * All rights reserved.
  11  *
  12  * This file is part of the VFlib Library.  This library is free
  13  * software; you can redistribute it and/or modify it under the terms of
  14  * the GNU Library General Public License as published by the Free
  15  * Software Foundation; either version 2 of the License, or (at your
  16  * option) any later version.  This library is distributed in the hope
  17  * that it will be useful, but WITHOUT ANY WARRANTY; without even the
  18  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  19  * PURPOSE.  See the GNU Library General Public License for more details.
  20  * You should have received a copy of the GNU Library General Public
  21  * License along with this library; if not, write to the Free Software
  22  * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23  */
  24 
  25 
  26 Private GF_GLYPH  gf_loader(VF_CACHE,FILE*);
  27 Private int       gf_read_glyph(FILE*,VF_BITMAP);
  28 
  29 Private unsigned char   bit_table[] = {
  30   0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  31 
  32 
  33 Private GF_GLYPH
  34 GF_CacheLoader(VF_CACHE c, char *font_path, int l)
     /* [<][>][^][v][top][bottom][index][help] */
  35 {
  36   FILE      *fp;
  37   UINT1      pre, id;
  38   UINT4      k;
  39 
  40   if (font_path == NULL)
  41     return NULL;
  42   if ((fp = vf_fm_OpenBinaryFileStream(font_path)) == NULL)
  43     return NULL;
  44 
  45   pre = READ_UINT1(fp);
  46   if (pre != GF_PRE)
  47     return NULL;
  48   id = READ_UINT1(fp);
  49   if (id != GF_ID)
  50     return NULL;
  51   k = READ_UINT1(fp);
  52   SKIP_N(fp, k);
  53 
  54   return gf_loader(c, fp);
  55 }
  56 
  57 Private void
  58 GF_CacheDisposer(GF_GLYPH go)
     /* [<][>][^][v][top][bottom][index][help] */
  59 {
  60   int   nc, i;
  61 
  62   if (go != NULL){
  63     if (go->bm_table != NULL){
  64       nc = go->code_max - go->code_min + 1;
  65       for (i = 0; i < nc; i++)
  66         vf_free(go->bm_table[i].bitmap);
  67       vf_free(go->bm_table);
  68     }
  69     vf_free(go);
  70   }
  71 }
  72 
  73 
  74 
  75 Private GF_GLYPH
  76 gf_loader(VF_CACHE c, FILE* fp)
     /* [<][>][^][v][top][bottom][index][help] */
  77 {
  78   GF_GLYPH    go;
  79   VF_BITMAP   bm;
  80   UINT1       instr, d;
  81   UINT4       ds, check_sum, hppp, vppp;
  82   INT4        min_m, max_m, min_n, max_n;
  83   INT4        w;
  84   UINT4       code;
  85   double      dx, dy;
  86   long        ptr_post, ptr_p, ptr, optr, gptr;
  87   int         bc, ec, nchars, i;
  88 
  89   go = NULL;
  90   nchars = -1;
  91 
  92   /* seek to post_post instr. */
  93   fseek(fp, -1, SEEK_END);
  94   while ((d = READ_UINT1(fp)) == 223)
  95     fseek(fp, -2, SEEK_CUR);
  96   if (d != GF_ID){
  97     vf_error = VF_ERR_ILL_FONT_FILE;
  98     goto ErrExit;
  99   }
 100   fseek(fp, -6, SEEK_CUR);
 101 
 102   /* check if the code is post_post */
 103   if (READ_UINT1(fp) != GF_POST_POST){
 104     vf_error = VF_ERR_ILL_FONT_FILE;
 105     goto ErrExit;
 106   }
 107 
 108   /* read pointer to post instr. */
 109   if ((ptr_post = READ_UINT4(fp)) == -1){
 110     vf_error = VF_ERR_ILL_FONT_FILE;
 111     goto ErrExit;
 112   }
 113 
 114   /* goto post instr. and read it */
 115   fseek(fp, ptr_post, SEEK_SET);
 116   if (READ_UINT1(fp) != GF_POST){
 117     vf_error = VF_ERR_ILL_FONT_FILE;
 118     goto ErrExit;
 119   }
 120   ptr_p     = READ_UINT4(fp);
 121   ds        = READ_UINT4(fp);
 122   check_sum = READ_UINT4(fp);
 123   hppp      = READ_UINT4(fp);
 124   vppp      = READ_UINT4(fp);
 125   min_m     = READ_INT4(fp);
 126   max_m     = READ_INT4(fp);
 127   min_n     = READ_INT4(fp);
 128   max_n     = READ_INT4(fp);
 129 
 130   gptr = ftell(fp);
 131 
 132 #if 0
 133   /* read min & max char code */
 134   bc = 256;
 135   ec = -1;
 136   for (;;){
 137     instr = READ_UINT1(fp);
 138     if (instr == GF_POST_POST){
 139       break;
 140     } else if (instr == GF_CHAR_LOC){
 141       code = READ_UINT1(fp);
 142       (void)SKIP_N(fp, 16);
 143     } else if (instr == GF_CHAR_LOC0){
 144       code = READ_UINT1(fp);
 145       (void)SKIP_N(fp, 9);
 146     } else {
 147       vf_error = VF_ERR_ILL_FONT_FILE;
 148       goto ErrExit;
 149     }
 150     if (code < bc)
 151       bc = code;
 152     if (code > ec)
 153       ec = code;
 154   }
 155 #else
 156   bc = 0;
 157   ec = 255;
 158 #endif
 159 
 160   nchars = ec - bc + 1;
 161   ALLOC_IF_ERR(go, struct s_gf_glyph){
 162     vf_error = VF_ERR_NO_MEMORY;
 163     goto ErrExit;
 164   }
 165   ALLOCN_IF_ERR(go->bm_table, struct vf_s_bitmap, nchars){
 166     vf_error = VF_ERR_NO_MEMORY;
 167     goto ErrExit;
 168   }
 169 
 170   for (i = 0; i < nchars; i++)
 171     go->bm_table[i].bitmap = NULL;
 172   go->ds   = (double)ds/(1<<20);
 173   go->hppp = (double)hppp/(1<<16);
 174   go->vppp = (double)vppp/(1<<16);
 175   go->font_bbx_w = max_m - min_m;
 176   go->font_bbx_h = max_n - min_n;
 177   go->font_bbx_xoff = min_m;
 178   go->font_bbx_yoff = min_n;
 179   go->code_min = bc;
 180   go->code_max = ec;
 181 
 182   /* read glyph */
 183 #if 0
 184   fseek(fp, gptr, SEEK_SET);
 185 #endif
 186   for (;;){
 187     if ((instr = READ_UINT1(fp)) == GF_POST_POST)
 188       break;
 189     switch ((int)instr){
 190     case GF_CHAR_LOC:
 191       code = READ_UINT1(fp);
 192       dx   = (double)READ_INT4(fp)/(double)(1<<16);
 193       dy   = (double)READ_INT4(fp)/(double)(1<<16);
 194       w    = READ_INT4(fp);
 195       ptr  = READ_INT4(fp);
 196       break;
 197     case GF_CHAR_LOC0:
 198       code = READ_UINT1(fp);
 199       dx   = (double)READ_INT1(fp);
 200       dy   = (double)0;
 201       w    = READ_INT4(fp);
 202       ptr  = READ_INT4(fp);
 203       break;
 204     default:
 205       vf_error = VF_ERR_ILL_FONT_FILE;
 206       goto ErrExit;
 207     }
 208     optr = ftell(fp);
 209     fseek(fp, ptr, SEEK_SET);
 210     bm = &go->bm_table[code - bc];
 211     if (gf_read_glyph(fp, bm) < 0)
 212       goto ErrExit;
 213     bm->mv_x = dx;
 214     bm->mv_y = dy;
 215     fseek(fp, optr, SEEK_SET);
 216   }
 217   return go;
 218   
 219 ErrExit:
 220 printf("*ERROR\n");
 221   if (go != NULL){
 222     if (go->bm_table != NULL){
 223       for (i = 0; i < nchars; i++)
 224         vf_free(go->bm_table[i].bitmap);
 225     }
 226     vf_free(go->bm_table);
 227   }
 228   vf_free(go);
 229   return NULL;
 230 }
 231 
 232 Private int
 233 gf_read_glyph(FILE* fp, VF_BITMAP bm)
     /* [<][>][^][v][top][bottom][index][help] */
 234 {
 235   long           m, n;
 236   int            paint_sw;
 237   int            instr;
 238   INT4           min_m, max_m, min_n, max_n, del_m, del_n;
 239   long           w, h, d;
 240   int            m_b, k;
 241   unsigned char  *ptr;
 242 
 243   switch (READ_UINT1(fp)){
 244   case GF_BOC:
 245     SKIP_N(fp, 4);
 246     SKIP_N(fp, 4);
 247     min_m = READ_INT4(fp);
 248     max_m = READ_INT4(fp);
 249     min_n = READ_INT4(fp);
 250     max_n = READ_INT4(fp);
 251     break;
 252   case GF_BOC1:
 253     SKIP_N(fp, 1);
 254     del_m = (INT4)READ_UINT1(fp);
 255     max_m = (INT4)READ_UINT1(fp);
 256     del_n = (INT4)READ_UINT1(fp);
 257     max_n = (INT4)READ_UINT1(fp);
 258     min_m = max_m - del_m;
 259     min_n = max_n - del_n;
 260     break;
 261   default:
 262     return -1;
 263   }
 264 
 265   w = max_m - min_m + 1;
 266   h = max_n - min_n + 1;
 267   if ((w < 0) || (h < 0)){
 268     vf_error = VF_ERR_ILL_FONT_FILE;
 269     return -1;
 270   }
 271 
 272   if ((bm->bitmap = (unsigned char*)malloc(h*((w+7)/8))) == NULL){
 273     vf_error = VF_ERR_NO_MEMORY;
 274     return -1;
 275   }
 276   memclr(bm->bitmap, h*((w+7)/8));
 277   bm->raster     = (w+7)/8;
 278   bm->bbx_width  = w;
 279   bm->bbx_height = h;
 280   bm->off_x      = -min_m;
 281   bm->off_y      = max_n;
 282 #if 0
 283   bm->mv_x       = -min_m;
 284   bm->mv_y       = max_n;
 285 #endif
 286 
 287   m        = min_m;
 288   n        = max_n;
 289   paint_sw = 0;
 290   while ((instr = (int)READ_UINT1(fp)) != GF_EOC){
 291     if (instr == GF_PAINT_0){
 292       paint_sw = 1 - paint_sw;
 293     } else if ((GF_NEW_ROW_0 <= instr) && (instr <= GF_NEW_ROW_164)){
 294       m        = min_m + (instr - GF_NEW_ROW_0);
 295       n        = n - 1;
 296       paint_sw = 1;
 297     } else if ((GF_PAINT_1 <= instr) && (instr <= GF_PAINT_63)){
 298       d = (instr - GF_PAINT_1 + 1);
 299       goto Paint;
 300     } else {
 301       switch ((int)instr){
 302       case GF_PAINT1:
 303       case GF_PAINT2:
 304       case GF_PAINT3:
 305         d = (UINT4)READ_UINTN(fp, (instr - GF_PAINT1 + 1));
 306 Paint:
 307         if (paint_sw == 0){
 308           m = m + d;
 309         } else {
 310           ptr = &bm->bitmap[(max_n - n) * bm->raster + (m - min_m)/8];
 311           m_b = (m - min_m) % 8;
 312           while (d > 0){
 313             *ptr |= bit_table[m_b];
 314             m++;
 315             if (++m_b >= 8){
 316               m_b = 0;
 317               ++ptr;
 318             }
 319             d--;
 320           }
 321         }
 322         paint_sw = 1 - paint_sw;
 323         break;
 324       case GF_SKIP0:
 325         m = min_m;
 326         n = n - 1;
 327         paint_sw = 0;
 328         break;
 329       case GF_SKIP1:
 330       case GF_SKIP2:
 331       case GF_SKIP3:
 332         m = min_m;
 333         n = n - (UINT4)READ_UINTN(fp, (instr - GF_SKIP1 + 1)) - 1;
 334         paint_sw = 0;
 335         break;
 336       case GF_XXX1:
 337       case GF_XXX2:
 338       case GF_XXX3:
 339       case GF_XXX4:
 340         k = READ_UINTN(fp, instr - GF_XXX1 + 1);
 341         SKIP_N(fp, k);
 342         break;
 343       case GF_YYY:
 344         SKIP_N(fp, 4);
 345         break;
 346       case GF_NO_OP:
 347         break;
 348       default:
 349         vf_free(bm->bitmap);
 350         bm->bitmap = NULL;
 351         vf_error = VF_ERR_ILL_FONT_FILE;
 352         return -1;
 353       }
 354     }
 355   }
 356 
 357   return 0;
 358 }
 359 
 360 
 361 /*EOF*/

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