src/pk.c

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

FUNCTIONS

This source file includes following functions.
  1. PK_CacheLoader
  2. PK_CacheDisposer
  3. pk_loader
  4. pk_read_14
  5. pk_read_n14
  6. pk_read_packed_number
  7. pk_read_nyble_init
  8. pk_read_nyble

   1 /*
   2  * pk.c - TeX PK 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 PK_GLYPH  pk_loader(VF_CACHE,FILE*);
  27 Private int       pk_read_14(FILE*,int,int,UINT4,VF_BITMAP,long);
  28 Private int       pk_read_n14(FILE*,int,int,UINT4,VF_BITMAP,long);
  29 Private long      pk_read_packed_number(long*,FILE*,int);
  30 Private void      pk_read_nyble_init(int);
  31 Private int       pk_read_nyble(FILE*);
  32 
  33 Private unsigned char   bit_table[] = {
  34   0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  35 
  36 
  37 
  38 Private PK_GLYPH
  39 PK_CacheLoader(VF_CACHE c, char *font_path, int l)
     /* [<][>][^][v][top][bottom][index][help] */
  40 {
  41   FILE      *fp;
  42   UINT1      pre, id;
  43 
  44   if (font_path == NULL)
  45     return NULL;
  46   if ((fp = vf_fm_OpenBinaryFileStream(font_path)) == NULL)
  47     return NULL;
  48 
  49   pre = READ_UINT1(fp);
  50   if (pre != PK_PRE)
  51     return NULL;
  52 
  53   id = READ_UINT1(fp);
  54   if (id != PK_ID)
  55     return NULL;
  56 
  57   return pk_loader(c, fp);
  58 }
  59 
  60 Private void
  61 PK_CacheDisposer(PK_GLYPH go)
     /* [<][>][^][v][top][bottom][index][help] */
  62 {
  63   int   nc, i;
  64 
  65   if (go != NULL){
  66     if (go->bm_table != NULL){
  67       nc = go->code_max - go->code_min + 1;
  68       for (i = 0; i < nc; i++)
  69         vf_free(go->bm_table[i].bitmap);
  70       vf_free(go->bm_table);
  71     }
  72     vf_free(go);
  73   }
  74 }
  75 
  76 
  77 Private PK_GLYPH
  78 pk_loader(VF_CACHE c, FILE* fp)
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80   PK_GLYPH      go;
  81   UINT1         instr;
  82   UINT4         ds, check_sum, hppp, vppp, k;
  83   unsigned int  flag, dny_f, bw, ess, size;
  84   UINT4         cc, tfm, dx, dy, dm, w, h, rs; 
  85   INT4          hoff, voff, mv_x, mv_y;
  86   long          gptr;
  87   int           bc, ec, nchars, index, i;
  88 
  89   k         = READ_UINT1(fp);
  90   SKIP_N(fp, k);
  91   ds        = READ_UINT4(fp);
  92   check_sum = READ_UINT4(fp);
  93   hppp      = READ_UINT4(fp);
  94   vppp      = READ_UINT4(fp);
  95 
  96   gptr = ftell(fp);
  97 
  98 #if 0
  99   /* read min & max char code */
 100   bc = 256;
 101   ec = -1;
 102   for (;;){
 103     instr = READ_UINT1(fp);
 104     if (instr == PK_POST)
 105       break; 
 106     switch ((int) instr){
 107     case PK_XXX1:  k = (UINT4)READ_UINT1(fp); SKIP_N(fp, k); break;
 108     case PK_XXX2:  k = (UINT4)READ_UINT2(fp); SKIP_N(fp, k); break;
 109     case PK_XXX3:  k = (UINT4)READ_UINT3(fp); SKIP_N(fp, k); break;
 110     case PK_XXX4:  k = (UINT4)READ_UINT4(fp); SKIP_N(fp, k); break;
 111     case PK_YYY:   SKIP_N(fp, 4); break;
 112     case PK_NO_OP: break;
 113     default:
 114       size  = instr & 0x3; instr >>= 2;
 115       ess   = instr & 0x1; 
 116       if (ess == 0){                          /* short */
 117         rs = (UINT4)(size*256) + (UINT4)READ_UINT1(fp);
 118         cc   = (UINT4)READ_UINT1(fp);  
 119       } else if ((ess == 1) && (size != 3)){  /* extended short */
 120         rs = (UINT4)(size*65536) + (UINT4)READ_UINT2(fp);
 121         cc   = (UINT4)READ_UINT1(fp);  
 122       } else {                                /* standard */
 123         rs   = READ_UINT4(fp);
 124         cc   = (UINT4)READ_UINT4(fp);  
 125       }
 126       SKIP_N(fp, rs);
 127       if (cc < bc)
 128         bc = cc;
 129       if (cc > ec)
 130         ec = cc;
 131       break;
 132     }
 133   }
 134 
 135 #else
 136   bc = 0;
 137   ec = 255;
 138 #endif
 139 
 140   nchars = ec - bc + 1;
 141   ALLOC_IF_ERR(go, struct s_pk_glyph)
 142     return NULL;
 143   ALLOCN_IF_ERR(go->bm_table, struct vf_s_bitmap, nchars){
 144     vf_free(go);
 145     return NULL;
 146   }
 147   for (i = 0; i < nchars; i++)
 148     go->bm_table[i].bitmap = NULL;
 149   go->ds   = (double)ds/(1<<20);
 150   go->hppp = (double)hppp/(1<<16);
 151   go->vppp = (double)vppp/(1<<16);
 152   go->font_bbx_w = 0;
 153   go->font_bbx_h = 0;
 154   go->font_bbx_xoff = 0;
 155   go->font_bbx_yoff = 0;
 156   go->code_min = bc;
 157   go->code_max = ec;
 158 
 159   /* read glyphs */
 160   fseek(fp, gptr, SEEK_SET);
 161   for (;;){
 162     if ((instr = READ_UINT1(fp)) == PK_POST)
 163       break;
 164     switch ((int)instr){
 165     case PK_XXX1:  k = (UINT4)READ_UINT1(fp); SKIP_N(fp, k); break;
 166     case PK_XXX2:  k = (UINT4)READ_UINT2(fp); SKIP_N(fp, k); break;
 167     case PK_XXX3:  k = (UINT4)READ_UINT3(fp); SKIP_N(fp, k); break;
 168     case PK_XXX4:  k = (UINT4)READ_UINT4(fp); SKIP_N(fp, k); break;
 169     case PK_YYY:   SKIP_N(fp, 4); break;
 170     case PK_NO_OP: break;
 171     default:
 172       flag = instr;
 173       size  = flag % 0x04;  flag = flag >> 2;
 174       ess   = flag % 0x02;  flag = flag >> 1;
 175       bw    = flag % 0x02;  flag = flag >> 1;
 176       dny_f = flag % 0x10;
 177       if (ess == 0){                          /* short */
 178         rs = (UINT4)(size*256) + (UINT4)READ_UINT1(fp) - (UINT4)8; 
 179         cc   = (UINT4)READ_UINT1(fp);   tfm  = (UINT4)READ_UINT3(fp);
 180         dm   = (UINT4)READ_UINT1(fp);
 181         w    = (UINT4)READ_UINT1(fp);   h    = (UINT4)READ_UINT1(fp);
 182         hoff = (INT4)READ_INT1(fp);     voff = (INT4)READ_INT1(fp);
 183         mv_x = dm;
 184         mv_y = 0;
 185       } else if ((ess == 1) && (size != 3)){  /* extended short */
 186         rs = (UINT4)(size*65536) + (UINT4)READ_UINT2(fp) - (UINT4)13; 
 187         cc   = (UINT4)READ_UINT1(fp);   tfm  = (UINT4)READ_UINT3(fp);
 188         dm   = (UINT4)READ_UINT2(fp);
 189         w    = (UINT4)READ_UINT2(fp);   h    = (UINT4)READ_UINT2(fp);
 190         hoff = (INT4)READ_INT2(fp);     voff = (INT4)READ_INT2(fp);
 191         mv_x = dm;
 192         mv_y = 0;
 193       } else {                                /* standard */
 194         rs   = READ_UINT4(fp) - (UINT4)28;
 195         cc   = READ_UINT4(fp);          tfm  = READ_UINT4(fp);
 196         dx   = READ_UINT4(fp);          dy   = READ_UINT4(fp);
 197         w    = READ_UINT4(fp);          h    = READ_UINT4(fp);
 198         hoff = READ_INT4(fp);           voff = READ_INT4(fp);
 199         mv_x = (double)dx/(double)(1<<16);
 200         mv_y = (double)dy/(double)(1<<16);
 201       }
 202       if ((cc < go->code_min) || (go->code_max < cc)){
 203         vf_error = VF_ERR_ILL_CODE_POINT;
 204         goto Error;
 205       }
 206       index = cc - go->code_min;
 207       go->bm_table[index].bbx_width  = w;
 208       go->bm_table[index].bbx_height = h;
 209       go->bm_table[index].raster = (w+7)/8;
 210       go->bm_table[index].off_x  = -hoff;
 211       go->bm_table[index].off_y  = voff;
 212       go->bm_table[index].mv_x   = mv_x;
 213       go->bm_table[index].mv_y   = mv_y;
 214       go->bm_table[index].bitmap = (unsigned char*)malloc(h*((w+7)/8));
 215       if (go->bm_table[index].bitmap == NULL){
 216         vf_error = VF_ERR_NO_MEMORY;
 217         goto Error;
 218       }
 219       memclr(go->bm_table[index].bitmap, h*((w+7)/8));
 220       if (dny_f == 14){
 221         if (pk_read_14(fp, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0){
 222           vf_error = VF_ERR_ILL_FONT_FILE;
 223           goto Error;
 224         }
 225       } else {
 226         if (pk_read_n14(fp, dny_f, bw, rs, &(go->bm_table[index]), cc) < 0){
 227           vf_error = VF_ERR_ILL_FONT_FILE;
 228           goto Error;
 229         }
 230       }
 231       if (go->font_bbx_w < w)
 232         go->font_bbx_w = w;
 233       if (go->font_bbx_h < h)
 234         go->font_bbx_h = h;
 235       if (go->font_bbx_xoff > -hoff)
 236         go->font_bbx_xoff = -hoff;
 237       if (go->font_bbx_yoff > (voff - h))
 238         go->font_bbx_yoff = (voff - h);
 239     }
 240   }
 241   return go;
 242 
 243 Error:
 244   for (i = 0; i < nchars; i++){
 245     if (go->bm_table[i].bitmap != NULL)
 246       vf_free(go->bm_table[i].bitmap);
 247   }
 248   vf_free(go->bm_table);
 249   vf_free(go);
 250   return NULL;
 251 }
 252 
 253 Private int
 254 pk_read_14(FILE* fp, int dyn_f, int bw, UINT4 rs, VF_BITMAP bm, long cc)
     /* [<][>][^][v][top][bottom][index][help] */
 255 {
 256   long           x, y, x8, xm;
 257   unsigned char  *bm_ptr;
 258   unsigned long  bit16_buff;
 259   int            rest_bit16_buff;
 260   static unsigned int mask_table[] = 
 261     { 0xdead,   0x80,   0xc0,   0xe0,   0xf0,   0xf8,   0xfc,   0xfe, 0xdead };
 262   
 263   if (rs == 0)
 264     return 0;
 265 
 266   x8 = bm->bbx_width / 8;
 267   xm = bm->bbx_width % 8;
 268   bm_ptr = bm->bitmap;
 269 
 270   bit16_buff = READ_UINT1(fp) << 8; 
 271   rest_bit16_buff = 8;
 272   --rs;
 273 
 274   for(y = 0; y < bm->bbx_height; y++){
 275     for(x = 0; x < x8; x++){
 276       *(bm_ptr++) = bit16_buff >> 8;
 277       rest_bit16_buff -= 8;
 278       bit16_buff = (bit16_buff << 8) & 0xffff;
 279       if (rs > 0){
 280         bit16_buff |= (READ_UINT1(fp) << (8 - rest_bit16_buff));
 281         rest_bit16_buff += 8;
 282         --rs;
 283       }
 284     }
 285     if (xm != 0){
 286       *(bm_ptr++) = (bit16_buff >> 8) & mask_table[xm];
 287       rest_bit16_buff -= xm;
 288       bit16_buff = (bit16_buff << xm) & 0xffff;
 289       if (rest_bit16_buff < 8){
 290         if (rs > 0){
 291           bit16_buff |= (READ_UINT1(fp) << (8 - rest_bit16_buff));
 292           rest_bit16_buff += 8;
 293           --rs;
 294         }
 295       }
 296     }
 297   }
 298 
 299   return 0;
 300 }
 301 
 302 Private int
 303 pk_read_n14(FILE* fp, int dyn_f, int bw, UINT4 rs, VF_BITMAP bm, long cc)
     /* [<][>][^][v][top][bottom][index][help] */
 304 {
 305   long           x, y, xx, yy, repeat;
 306   int            bits, b_p;
 307   unsigned char  *p, *p0, *p1;
 308 
 309   pk_read_nyble_init(rs);
 310   p    = bm->bitmap;
 311   bw   = 1-bw;
 312   bits = 0;
 313   for (y = 0; y < bm->bbx_height; ){
 314     b_p    = 0;
 315     repeat = 0;
 316     p0     = p;
 317     for (x = 0; x < bm->bbx_width; x++){
 318       if (bits == 0){
 319         bw   = 1-bw;
 320         if ((bits = pk_read_packed_number(&repeat, fp, dyn_f)) < 0)
 321           return -1;
 322       }
 323       if (bw == 1)
 324         *p = *p | bit_table[b_p];
 325       --bits;
 326       if (++b_p >= 8){
 327         b_p = 0;
 328         p++;
 329       }
 330     }
 331     if (b_p != 0)
 332       p++;
 333     y++;
 334     for (yy = 0; yy < repeat; yy++){
 335       p1 = p0;
 336       for (xx = 0; xx < bm->raster; xx++)
 337         *(p++) = *(p1++);
 338       y++;
 339     }
 340   }
 341   return 0;
 342 }
 343 
 344 Private long
 345 pk_read_packed_number(long* repeat, FILE* fp, int dyn_f)
     /* [<][>][^][v][top][bottom][index][help] */
 346 {
 347   int   d, n;
 348   long  di;
 349   
 350 entry:
 351   d = pk_read_nyble(fp);
 352   if (d == 0){
 353     n = 0; 
 354     do {
 355       di = pk_read_nyble(fp);
 356       n++;
 357     } while (di == 0);
 358     for ( ; n > 0; n--)
 359       di = di*16 + pk_read_nyble(fp); 
 360     return di - 15 + (13 - dyn_f)*16 + dyn_f;
 361   } 
 362   if (d <= dyn_f)
 363     return d;
 364   if (d <= 13)
 365     return (d - dyn_f - 1)*16 + pk_read_nyble(fp) + dyn_f + 1;
 366   *repeat = 1;
 367   if (d == 14)
 368     *repeat = pk_read_packed_number(repeat, fp, dyn_f);
 369   goto entry;
 370 }
 371 
 372 Private int  pk_read_nyble_rest_cnt; 
 373 Private int  pk_read_nyble_max_bytes; 
 374 
 375 Private void
 376 pk_read_nyble_init(int max)
     /* [<][>][^][v][top][bottom][index][help] */
 377 {
 378   pk_read_nyble_rest_cnt  = 0;
 379   pk_read_nyble_max_bytes = max;
 380 }
 381 
 382 Private int
 383 pk_read_nyble(FILE* fp)
     /* [<][>][^][v][top][bottom][index][help] */
 384 {
 385   static UINT1  d; 
 386   int           v;
 387 
 388   switch (pk_read_nyble_rest_cnt){
 389   case 0:
 390     d = READ_UINT1(fp);
 391     if (--pk_read_nyble_max_bytes < 0)
 392       return -1L;
 393     v = d / 0x10;
 394     d = d % 0x10;
 395     pk_read_nyble_rest_cnt = 1;    
 396     break;
 397   case 1:
 398   default:
 399     v = d;
 400     pk_read_nyble_rest_cnt = 0;
 401     break;
 402   }
 403 
 404   return v;
 405 }
 406 
 407 /*EOF*/

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