home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / g / gs241j11.zip / ZKFJTEX.C < prev    next >
C/C++ Source or Header  |  1992-06-09  |  25KB  |  1,308 lines

  1. /*
  2.  * zkfjtex.c --- Kanji font operator for JTeX PK format file
  3.  *
  4.  * Copyright (C) 1992 Norio Katayama.
  5.  * Apr. 27, 1992 Programmed by N.Katayama (katayama@nacsis.ac.jp)
  6.  */
  7.  
  8. #include "memory_.h"
  9. #include "ghost.h"
  10. #include "oper.h"
  11. #include "errors.h"
  12. #include "gsmatrix.h"
  13. #include "state.h"
  14. #include "store.h"
  15.  
  16. #undef DEBUG
  17.  
  18. #define B_X_CL    500    /* horizontal center in BuildChar */
  19. #define B_Y_CL    400    /* vertical center in BuildChar */
  20. #define B_Y_RP    0    /* reference point in BuildChar */
  21. #define B_X_EX    1000    /* horizontal extent in BuildChar */
  22.  
  23. #define FP_CACHE_SIZE    10
  24.  
  25. /* Imported procedures */
  26.  
  27. extern int kf_is_vchar(P1(int));
  28. extern int kf_vmatrix(P5(int, floatp, floatp, gs_rect *, gs_matrix *));
  29. extern int gs_imagebbox(P6(int width, int height, int bool, 
  30.                gs_matrix *pmat, byte *image, gs_rect *));
  31.  
  32. /* Forward declaration */
  33.  
  34. private int jteximage(P9(char *, int, int *, int *, byte *, int,
  35.             gs_matrix *, floatp *, floatp *));
  36.  
  37. /*
  38.  * zkfjtex
  39.  */
  40.  
  41. int
  42. zkfjtex(register os_ptr op)
  43. {
  44.     char *buffer;
  45.     int code, len, width, height, length;
  46.     int jis_code, wmode;
  47.     byte *bitmap;
  48.     floatp w0x, w0y;
  49.     gs_matrix *pmat, vmat, imat;
  50.     gs_rect bbox;
  51.  
  52.     check_type(op[-4], t_integer);        /* JIS Code */
  53.     check_type(op[-3], t_integer);        /* WMode */
  54.     if((code = write_matrix(op - 2)) < 0)    /* ImageMatrix */
  55.         return code;
  56.     check_type(op[-1], t_string);        /* ImageString */
  57.     check_type(op[0], t_string);        /* FileName */
  58.  
  59.     len = r_size(op);
  60.     if((buffer = gs_malloc(len + 1, 1, "zkfjtex")) == 0)
  61.         return e_VMerror;
  62.     memcpy(buffer, (char *)op->value.bytes, len);
  63.     buffer[len] = 0;
  64.  
  65.     jis_code = op[-4].value.intval;
  66.     wmode = op[-3].value.intval;
  67.  
  68.     bitmap = op[-1].value.bytes;
  69.     length = r_size(op - 1);
  70.     pmat = (gs_matrix *)op[-2].value.refs;
  71.  
  72.     if((code = jteximage(buffer, jis_code, 
  73.                  &width, &height, bitmap, length, 
  74.                  pmat, &w0x, &w0y)) < 0)
  75.         return code;
  76.  
  77.     if((code = gs_imagebbox(width, height, 1, pmat, bitmap, &bbox)) < 0)
  78.         return code;
  79.  
  80.     if(wmode && kf_is_vchar(jis_code)) {
  81.         kf_vmatrix(jis_code, 
  82.                (floatp)B_X_CL, (floatp)B_Y_CL, &bbox, &vmat);
  83.         gs_matrix_invert(&vmat, &imat);
  84.         gs_matrix_multiply(&imat, pmat, pmat);
  85.     }
  86.  
  87.     /* Push results */
  88.     /* w0x w0y llx lly urx ury width height bool matrix bitmap */
  89.     push(6);
  90.     make_real(op - 10, w0x);
  91.     make_real(op - 9, w0y);
  92.     make_real(op - 8, bbox.p.x);
  93.     make_real(op - 7, bbox.p.y);
  94.     make_real(op - 6, bbox.q.x);
  95.     make_real(op - 5, bbox.q.y);
  96.     make_int(op - 4, width);
  97.     make_int(op - 3, height);
  98.     make_bool(op - 2 , 1);
  99.     make_tasv(op - 1, t_array, a_all, 6, refs, (ref *)pmat);
  100.     make_tasv(op, t_string, a_all, length, bytes, bitmap);
  101.     gs_free(buffer, len + 1, 1, "zkfjtex");
  102.     return 0;
  103. }
  104.  
  105. /* -------- Initialization procedure -------- */
  106.  
  107. op_def zkfjtex_op_defs[] = {
  108.     {"5kfjtex", zkfjtex},
  109.     op_def_end(0)
  110. };
  111.  
  112. /* -------- Internal Routines -------- */
  113.  
  114. #define FIXED16(fixed)    ((double)(fixed) / 0x10000)
  115. #define FIXED20(fixed)    ((double)(fixed) / 0x100000)
  116.  
  117. /*
  118.  * Preamble structure
  119.  */
  120.  
  121. typedef struct preamble_s {
  122.     ulong i;    /* identifier */
  123.     /* x[k] */
  124.     double ds;    /* design size */
  125.     ulong cs;    /* check sum */
  126.     double hppp;    /* pixel per point */
  127.     double vppp;    /* pixel per point */
  128. } preamble;
  129.     
  130. /*
  131.  * Glyph data structure
  132.  */
  133.  
  134. typedef struct glyph_data_s {
  135.     ulong flag;
  136.     ulong pl;    /* packet length */
  137.     ulong cc;    /* character code */
  138.     double tfm;
  139.     double dx;
  140.     double dy;
  141.     ulong w;
  142.     ulong h;
  143.     long hoff;
  144.     long voff;
  145.     ulong rs;
  146. } glyph_data;
  147.  
  148. /*
  149.  * Read bits from PK file
  150.  */
  151.  
  152. private long
  153. fget32(FILE *fp)
  154. {
  155.     ulong u;
  156.  
  157.     u = fgetc(fp);
  158.     u = (u << 8) + fgetc(fp);
  159.     u = (u << 8) + fgetc(fp);
  160.     u = (u << 8) + fgetc(fp);
  161.  
  162.     return (long)u;
  163. }
  164.  
  165. private long
  166. fget24(FILE *fp)
  167. {
  168.     ulong u;
  169.  
  170.     u = fgetc(fp);
  171.     u = (u << 8) + fgetc(fp);
  172.     u = (u << 8) + fgetc(fp);
  173.  
  174.     return (long)(u << 8) >> 8;
  175. }
  176.  
  177. private short
  178. fget16(FILE *fp)
  179. {
  180.     ulong u;
  181.  
  182.     u = fgetc(fp);
  183.     u = (u << 8) + fgetc(fp);
  184.  
  185.     return (short)u;
  186. }
  187.  
  188. /*
  189.  * Skip NOP operator
  190.  */
  191.  
  192. private int
  193. skip_nop(FILE *fp)
  194. {
  195.     int c;
  196.     ulong k;
  197.  
  198.     for(;;) {
  199.         switch(c = fgetc(fp)) {
  200.         case 240:    /* pk_xxx1 */
  201.             k = fgetc(fp);
  202.             fseek(fp, k, 1);
  203.             break;
  204.         case 241:    /* pk_xxx2 */
  205.             k = fget16(fp);
  206.             fseek(fp, k, 1);
  207.             break;
  208.         case 242:    /* pk_xxx3 */
  209.             k = fget24(fp);
  210.             fseek(fp, k, 1);
  211.             break;
  212.         case 243:    /* pk_xxx4 */
  213.             k = fget32(fp);
  214.             fseek(fp, k, 1);
  215.             break;
  216.         case 244:    /* pk_yyy */
  217.             fget32(fp);
  218.             break;
  219.         case 246:    /* pk_no_op */
  220.             break;
  221.         default:
  222.             ungetc(c, fp);
  223.             return 0;
  224.         }
  225.  
  226.         if(ferror(fp) || feof(fp))
  227.             return -1;
  228.     }
  229. }
  230.  
  231. /*
  232.  * Read preamble
  233.  */
  234.  
  235. private int
  236. read_preamble(FILE *fp, preamble *pa)
  237. {
  238.     int k;
  239.  
  240.     if(skip_nop(fp) < 0)
  241.         return -1;
  242.  
  243.     if(fgetc(fp) != 247)
  244.         return -1;
  245.  
  246.     if((pa->i = fgetc(fp)) != 89)
  247.         return -1;
  248.  
  249.     k = fgetc(fp);
  250.     fseek(fp, k, 1);
  251.     pa->ds = FIXED20(fget32(fp));
  252.     pa->cs = fget32(fp);
  253.     pa->hppp = FIXED16(fget32(fp));
  254.     pa->vppp = FIXED16(fget32(fp));
  255.  
  256.     if(ferror(fp) || feof(fp))
  257.         return -1;
  258.  
  259.     return 0;
  260. }
  261.  
  262. /*
  263.  * Read postamble
  264.  */
  265.  
  266. private int
  267. read_postamble(FILE *fp)
  268. {
  269.     int c;
  270.  
  271.     if(skip_nop(fp) < 0)
  272.         return -1;
  273.  
  274.     if((c = fgetc(fp)) != 245)
  275.         return -1;
  276.  
  277.     return 0;
  278. }
  279.  
  280. /*
  281.  * Glyph data
  282.  */
  283.  
  284. private void
  285. long_format(FILE *fp, glyph_data *data)
  286. {
  287.     data->pl = fget32(fp);
  288.     data->cc = fget32(fp);
  289.     data->tfm = FIXED20(fget32(fp));
  290.     data->dx = FIXED16(fget32(fp));
  291.     data->dy = FIXED16(fget32(fp));
  292.     data->w = fget32(fp);
  293.     data->h = fget32(fp);
  294.     data->hoff = fget32(fp);
  295.     data->voff = fget32(fp);
  296.     data->rs = data->pl - 37 + 8;
  297. #ifdef DEBUG
  298.     fprintf(stderr, "long format (cc = %02X).\n", data->cc);
  299. #endif
  300. }
  301.  
  302. private void
  303. extended_format(FILE *fp, glyph_data *data)
  304. {
  305.     data->pl = fget16(fp);
  306.     data->cc = fgetc(fp);
  307.     data->tfm = FIXED20(fget24(fp));
  308.     data->dx = fget16(fp);
  309.     data->dy = 0;
  310.     data->w = fget16(fp);
  311.     data->h = fget16(fp);
  312.     data->hoff = fget16(fp);
  313.     data->voff = fget16(fp);
  314.     data->rs = ((data->flag & 0x03) << 16) + data->pl - 17 + 3;
  315.  
  316. #ifdef DEBUG
  317.     fprintf(stderr, "extended format (cc = %02X).\n", data->cc);
  318. #endif
  319. }
  320.  
  321. private void
  322. short_format(FILE *fp, glyph_data *data)
  323. {
  324.     data->pl = fgetc(fp);
  325.     data->cc = fgetc(fp);
  326.     data->tfm = FIXED20(fget24(fp));
  327.     data->dx = fgetc(fp);
  328.     data->dy = 0;
  329.     data->w = fgetc(fp);
  330.     data->h = fgetc(fp);
  331.     data->hoff = (char)fgetc(fp);
  332.     data->voff = (char)fgetc(fp);
  333.     data->rs = ((data->flag & 0x03) << 8) + data->pl - 11 + 3;
  334. #ifdef DEBUG
  335.     fprintf(stderr, "short format (cc = %02X).\n", data->cc);
  336. #endif
  337. }
  338.  
  339. /*
  340.  * Read glyph data
  341.  */
  342.  
  343. private int
  344. read_glyph_data(FILE *fp, glyph_data *data)
  345. {
  346.     data->flag = fgetc(fp);
  347.     if((data->flag & 0xf0) == 0xf0) {
  348.         ungetc(data->flag, fp);
  349.         return EOF;
  350.     }
  351.  
  352.     if((data->flag & 0x07) == 0x07)
  353.         long_format(fp, data);
  354.     else if((data->flag & 0x04) == 0x04)
  355.         extended_format(fp, data);
  356.     else
  357.         short_format(fp, data);
  358.  
  359.     return data->rs;
  360. }
  361.  
  362. /*
  363.  * Glyph index
  364.  */
  365.  
  366. typedef struct glyph_index_s {
  367.     ulong cc;
  368.     long offset;
  369. } glyph_index;
  370.  
  371. /*
  372.  * PK file index
  373.  */
  374.  
  375. typedef struct pk_index_s {
  376.     preamble pa;
  377.     int num_glyphs;
  378.     glyph_index *gi;
  379. } pk_index, *pk_index_ptr;
  380.  
  381. /*
  382.  * Make PK index
  383.  */
  384.  
  385. #define INIT_GI_SIZE    4
  386.  
  387. private int
  388. make_pk_index(FILE *fp, pk_index *pi)
  389. {
  390.     int count;
  391.     glyph_data data;
  392.     static glyph_index *gi = NULL;
  393.     static int gi_size = 0;
  394.  
  395.     rewind(fp);
  396.  
  397.     if(read_preamble(fp, &pi->pa) < 0)
  398.         return -1;
  399.  
  400.     if(gi == NULL) {
  401.         if((gi = (glyph_index *)
  402.             malloc(sizeof(glyph_data)*INIT_GI_SIZE)) == NULL)
  403.             return -1;
  404.         gi_size = INIT_GI_SIZE;
  405.     }
  406.  
  407.     count = 0;
  408.     for(;;) {
  409.         if(count >= gi_size) {
  410.             if((gi = (glyph_index *)
  411.                 realloc(gi, sizeof(glyph_data)*gi_size*2)) == NULL)
  412.                 return -1;
  413.             gi_size *= 2;
  414.         }
  415.         gi[count].offset = ftell(fp);
  416.         if(read_glyph_data(fp, &data) < 0)
  417.             break;
  418.         gi[count].cc = data.cc;
  419.         fseek(fp, data.rs, 1);
  420.         count ++;
  421.     }
  422.  
  423.     if(read_postamble(fp) < 0)
  424.         return -1;
  425.  
  426.     if((pi->gi = (glyph_index *)malloc(sizeof(glyph_data)*count)) == NULL)
  427.         return -1;
  428.  
  429.     memcpy(pi->gi, gi, sizeof(glyph_data)*count);
  430.     pi->num_glyphs = count;
  431.  
  432.     return 0;
  433. }    
  434.  
  435. /*
  436.  * Bits Expander
  437.  */
  438.  
  439. private struct {
  440.     byte *bitmap;
  441.     int w, h;
  442.     int x, y;
  443.     int bw;
  444.     int repeat_count;
  445.     int w8;
  446. } bits_data;
  447.  
  448. /* Init Bits Data */
  449. private int
  450. init_bits(byte *bitmap, int w, int h, int bw)
  451. {
  452.     bits_data.bitmap = bitmap;
  453.     bits_data.w = w;
  454.     bits_data.h = h;
  455.     bits_data.x = 0;
  456.     bits_data.y = 0;
  457.     bits_data.bw = bw;
  458.     bits_data.w8 = (w - 1) / 8 + 1;
  459.     return 0;
  460. }
  461.  
  462. /* Forward Bit */
  463. private int
  464. forward_bit()
  465. {
  466.     int i;
  467.     byte *src, *dst;
  468.  
  469.     if(++ bits_data.x < bits_data.w)
  470.         return 0;
  471.  
  472.     /* new line */
  473.     bits_data.x = 0;
  474.     bits_data.y ++;
  475.  
  476.     if(bits_data.repeat_count == 0)
  477.         return 0;
  478.  
  479.     /* repeat line */
  480.     src = bits_data.bitmap + bits_data.w8*(bits_data.y - 1);
  481.  
  482.     for(i=0; i<bits_data.repeat_count; i++) {
  483.         dst = bits_data.bitmap + bits_data.w8*bits_data.y;
  484.         memcpy(dst, src, bits_data.w8);
  485.         bits_data.y ++;
  486.     }
  487.  
  488.     bits_data.repeat_count = 0;
  489.  
  490.     return 0;
  491. }
  492.     
  493. /* Set Bits */
  494. private int
  495. set_bits(ulong bit_count)
  496. {
  497.     int i, n;
  498.  
  499.     for(i=0; i<bit_count; i++) {
  500.         n = bits_data.x / 8 + bits_data.w8 * bits_data.y;
  501.         if(bits_data.bw)
  502.             bits_data.bitmap[n] |= 0x80 >> (bits_data.x % 8);
  503.         else
  504.             bits_data.bitmap[n] &= ~(0x80 >> (bits_data.x % 8));
  505.  
  506.         forward_bit();
  507.     }
  508.  
  509.     bits_data.bw = !bits_data.bw;
  510.     return 0;
  511. }
  512.  
  513. /* Set Repeat Count */
  514. private int
  515. set_repeat_count(ulong repeat_count)
  516. {
  517.     bits_data.repeat_count = repeat_count;
  518.     return 0;
  519. }
  520.     
  521. /* Bits Filled */
  522. private int
  523. bits_filled(void)
  524. {
  525.     if(bits_data.y >= bits_data.h)
  526.         return 1;
  527.     else
  528.         return 0;
  529. }
  530.  
  531. /*
  532.  * Unpack Glyph
  533.  */
  534.  
  535. private int
  536. unpack_glyph(glyph_data *data, byte *glyph, byte *bitmap)
  537. {
  538.     byte *ptr, mask, nybble;
  539.     long value, dyn_f = (data->flag & 0xf0) >> 4;
  540.     int repeat_count;
  541.     
  542.     ptr = glyph;
  543.     mask = 0xf0;
  544. #define get_nybble()    ((mask == 0xf0) ? \
  545.              (mask = 0x0f, (*ptr & 0xf0) >> 4) : \
  546.              (mask = 0xf0, (*ptr++ & 0x0f)))
  547.  
  548.     init_bits(bitmap, data->w, data->h, data->flag & 0x08);
  549.     repeat_count = 0;
  550.  
  551.     while(!bits_filled() && ptr < glyph + data->rs) {
  552.         if((nybble = get_nybble()) == 0) {
  553.             int count, i;
  554.             
  555.             count = 1;
  556.             while((nybble = get_nybble()) == 0)
  557.                 count ++;
  558.             value = nybble;
  559.             for(i = 0; i < count; i++)
  560.                 value = value * 16 + get_nybble();
  561.             value += (13 - dyn_f)*16 + dyn_f - 15;
  562. #ifdef DEBUG
  563.             fprintf(stderr, "0: {%d}, ", value);
  564. #endif
  565.             if(repeat_count) {
  566.                 set_repeat_count(value);
  567.                 repeat_count = 0;
  568.             }
  569.             else
  570.                 set_bits(value);
  571.         }
  572.         else if(nybble <= dyn_f) {
  573.             value = nybble;
  574. #ifdef DEBUG
  575.             fprintf(stderr, "1: {%d}, ", value);
  576. #endif
  577.             if(repeat_count) {
  578.                 set_repeat_count(value);
  579.                 repeat_count = 0;
  580.             }
  581.             else
  582.                 set_bits(value);
  583.         }
  584.         else if(nybble <= 13) {
  585.             value = (nybble - dyn_f - 1)*16 + 
  586.                 get_nybble() + dyn_f + 1;
  587. #ifdef DEBUG
  588.             fprintf(stderr, "2: {%d}, ", value);
  589. #endif
  590.             if(repeat_count) {
  591.                 set_repeat_count(value);
  592.                 repeat_count = 0;
  593.             }
  594.             else
  595.                 set_bits(value);
  596.         }
  597.         else if(nybble == 14) {
  598. #ifdef DEBUG
  599.             fprintf(stderr, "[], ");
  600. #endif
  601.             repeat_count = 1;
  602.         }
  603.         else {
  604. #ifdef DEBUG
  605.             fprintf(stderr, "[1], ");
  606. #endif
  607.             set_repeat_count(1);
  608.             repeat_count = 0;
  609.         }
  610.     }
  611.  
  612. #ifdef DEBUG
  613.     fprintf(stderr, "\n");
  614.     fprintf(stderr, "bits_data: x %d, y %d\n", bits_data.x, bits_data.y);
  615. #endif
  616.     return 0;
  617. }
  618.         
  619. /*
  620.  * Convert glyph into bitmap
  621.  */
  622.  
  623. private int
  624. glyph_to_bitmap(glyph_data *data, byte *glyph, byte *bitmap)
  625. {
  626.     if((data->flag & 0xf0) == 0xe0) {
  627.         /* bitmap */
  628.         int x, y, bmask, gmask;
  629.         byte *bptr, *gptr;
  630.  
  631.         bptr = bitmap;
  632.         gptr = glyph;
  633.         gmask = 0x80;
  634.         for(y = 0; y < data->h; y++) {
  635.             bmask = 0x80;
  636.             for(x = 0; x < data->w; x++) {
  637.                 if(*gptr & gmask)
  638.                     *bptr |= bmask;
  639.                 if((bmask >>= 1) == 0) {
  640.                     bptr ++;
  641.                     *bptr = 0;
  642.                     bmask = 0x80;
  643.                 }
  644.                 if((gmask >>= 1) == 0) {
  645.                     gptr ++;
  646.                     gmask = 0x80;
  647.                 }
  648.             }
  649.             if(bmask != 0x80)
  650.                 bptr ++;
  651.         }
  652.  
  653.         return 0;
  654.     }
  655.     else
  656.         return unpack_glyph(data, glyph, bitmap);
  657. }
  658.  
  659. /* -------- File Name Hash Index -------- */
  660.  
  661. typedef struct index_item_s {
  662.     struct index_item_s *next;
  663.     char *str;
  664.     int id;
  665. } index_item;
  666. private index_item *hash_index[256];
  667.  
  668. /* hash function */
  669.  
  670. private int
  671. hash(unsigned char *str)
  672. {
  673.         unsigned char hash;
  674.         for(hash = 0; *str != 0; str++)
  675.                 hash ^= *str;
  676.         return hash;
  677. }
  678.  
  679. /* file name id */
  680.  
  681. private int
  682. file_name_id(char *str)
  683. {
  684.     static int id = 0;
  685.  
  686.     int key = hash((unsigned char *)str);
  687.     index_item *item;
  688.  
  689.     item = hash_index[key];
  690.     while(item != 0) {
  691.         if(strcmp(item->str, str) == 0)
  692.             return item->id;
  693.  
  694.         item = item->next;
  695.     }
  696.  
  697.     /* Not Found */
  698.  
  699.     if((item = (index_item *)malloc(sizeof(index_item))) == 0)
  700.         return -1;
  701.     if((item->str = (char *)malloc(strlen(str) + 1)) == 0)
  702.         return -1;
  703.     strcpy(item->str, str);
  704.     item->next = hash_index[key];
  705.     item->id = id ++;
  706.     hash_index[key] = item;
  707.  
  708.     return item->id;
  709. }
  710.  
  711. /* -------- FILE Pointer Cache -------- */
  712.  
  713. typedef struct cache_item_s {
  714.     int prev;
  715.     int next;
  716.     int id;
  717.     FILE *fp;
  718. } cache_item;
  719.  
  720. private
  721. struct {
  722.     int head;
  723.     int used;
  724.     cache_item item[FP_CACHE_SIZE];
  725. } fp_cache;
  726.  
  727. /* store cache */
  728.  
  729. private int
  730. store_fp(int id, FILE *fp)
  731. {
  732.     if(fp_cache.used == 0) {
  733.         /* first */
  734.         fp_cache.item[0].prev = 0;
  735.         fp_cache.item[0].next = 0;
  736.         fp_cache.item[0].id = id;
  737.         fp_cache.item[0].fp = fp;
  738.  
  739.         fp_cache.head = 0;
  740.         fp_cache.used = 1;
  741.     }
  742.     else if(fp_cache.used < FP_CACHE_SIZE) {
  743.         int free, head, tail;
  744.  
  745.         free = fp_cache.used;
  746.         head = fp_cache.head;
  747.         tail = fp_cache.item[head].prev;
  748.  
  749.         /* put values */
  750.         fp_cache.item[free].prev = tail;
  751.         fp_cache.item[free].next = head;
  752.         fp_cache.item[free].id = id;
  753.         fp_cache.item[free].fp = fp;
  754.  
  755.         /* link to the cache chain */
  756.         fp_cache.item[head].prev = free;
  757.         fp_cache.item[tail].next = free;
  758.  
  759.         fp_cache.head = free;
  760.         fp_cache.used ++;
  761.     }
  762.     else {
  763.         int tail;
  764.  
  765.         /* close the LRU */
  766.         tail = fp_cache.item[fp_cache.head].prev;
  767.         fclose(fp_cache.item[tail].fp);
  768.  
  769.         /* put values */
  770.         fp_cache.item[tail].id = id;
  771.         fp_cache.item[tail].fp = fp;
  772.  
  773.         fp_cache.head = tail;
  774.     }
  775.  
  776.     return 0;
  777. }
  778.  
  779. /* search cache */
  780.  
  781. private int
  782. search_fp(int id, FILE **fp)
  783. {
  784.     int idx;
  785.     
  786.     if(fp_cache.used == 0)
  787.         return 0;
  788.  
  789.     idx = fp_cache.head;
  790.     do {
  791.         if(fp_cache.item[idx].id == id) {
  792.             /* move the MRU to the head */
  793.             if(idx != fp_cache.head) {
  794.                 int prev, next, head, tail;
  795.  
  796.                 prev = fp_cache.item[idx].prev;
  797.                 next = fp_cache.item[idx].next;
  798.  
  799.                 fp_cache.item[next].prev = prev;
  800.                 fp_cache.item[prev].next = next;
  801.  
  802.                 head = fp_cache.head;
  803.                 tail = fp_cache.item[head].prev;
  804.  
  805.                 fp_cache.item[head].prev = idx;
  806.                 fp_cache.item[tail].next = idx;
  807.                 fp_cache.item[idx].prev = tail;
  808.                 fp_cache.item[idx].next = head;
  809.  
  810.                 fp_cache.head = idx;
  811.             }
  812.  
  813.             *fp = fp_cache.item[idx].fp;
  814.  
  815.             return 1;
  816.         }
  817.     } while((idx = fp_cache.item[idx].next) != fp_cache.head);
  818.  
  819.     return 0;
  820. };
  821.  
  822. /* -------- PK Index Buffer -------- */
  823.  
  824. private 
  825. struct pk_index_buffer_s {
  826.     int size;
  827.     pk_index_ptr *ptr;
  828. } pi_buffer;
  829.  
  830. #define INIT_PI_BUFFER_SIZE    4
  831.  
  832. /* store pk index */
  833.  
  834. private int
  835. store_pk_index(int id, pk_index *pi)
  836. {
  837.     if(pi_buffer.size == 0) {
  838.         int size = INIT_PI_BUFFER_SIZE;
  839.         if((pi_buffer.ptr = (pk_index_ptr *)
  840.             malloc(sizeof(pk_index_ptr)*size)) == NULL)
  841.             return -1;
  842.         memset(pi_buffer.ptr, 0, sizeof(pk_index_ptr)*size);
  843.         pi_buffer.size = size;
  844.     }
  845.  
  846.     if(id >= pi_buffer.size) {
  847.         int size = pi_buffer.size;
  848.         while(id >= size)
  849.             size *= 2;
  850.         if((pi_buffer.ptr = (pk_index_ptr *)
  851.             realloc(pi_buffer.ptr, sizeof(pk_index_ptr)*size)) == NULL)
  852.             return -1;
  853.         memset(pi_buffer.ptr + pi_buffer.size, 0, 
  854.                sizeof(pk_index_ptr)*(size - pi_buffer.size));
  855.         pi_buffer.size = size;
  856.     }
  857.  
  858.     if((pi_buffer.ptr[id] = (pk_index *)malloc(sizeof(pk_index))) == NULL)
  859.         return -1;
  860.  
  861.     *pi_buffer.ptr[id] = *pi;
  862.  
  863.     return 0;
  864. }
  865.  
  866. /* search pk index */
  867.  
  868. private int
  869. search_pk_index(int id, pk_index *pi)
  870. {
  871.     if(id >= pi_buffer.size || pi_buffer.ptr[id] == NULL)
  872.         return 0;
  873.  
  874.     *pi = *pi_buffer.ptr[id];
  875.     return 1;
  876. }
  877.  
  878. /* -------- PK Font File Routines -------- */
  879.  
  880. typedef struct pk_file_s {
  881.     FILE *fp;
  882.     pk_index pi;
  883. } pk_file;
  884.  
  885. /*
  886.  * Open PK File
  887.  */
  888.  
  889. private int
  890. open_pk_file(char *file, pk_file *pf)
  891. {
  892.     int id;
  893.     FILE *fp;
  894.     pk_index pi;
  895.  
  896.     /* Hash Index */
  897.  
  898.     if((id = file_name_id(file)) < 0)
  899.         return -1;
  900.  
  901.     /* FILE Pointer Cache */
  902.  
  903.     if(!search_fp(id, &fp)) {
  904. #ifdef DEBUG
  905.         fprintf(stderr, "opening `%s'\n", file);
  906. #endif
  907.         if((fp = fopen(file, "r")) == NULL)
  908.             return -1;
  909.         store_fp(id, fp);
  910.     }
  911.  
  912.     /* PK Index Buffer */
  913.  
  914.     if(!search_pk_index(id, &pi)) {
  915.         if(make_pk_index(fp, &pi) < 0)
  916.             return -1;
  917.         store_pk_index(id, &pi);
  918.     }
  919.             
  920.     pf->fp = fp;
  921.     pf->pi = pi;
  922.  
  923.     return 0;
  924. }
  925.  
  926. /*
  927.  * Read Bitmap from PK File
  928.  */
  929.  
  930. #define INIT_GLYPH_SIZE        16
  931.  
  932. private int
  933. read_pk_bitmap(pk_file *pf, ulong cc, 
  934.            glyph_data *data, byte *bitmap, int length)
  935. {
  936.     int idx;
  937.     FILE *fp = pf->fp;
  938.     pk_index *pi = &pf->pi;
  939.     static byte *glyph = NULL;
  940.     static int glyph_size = 0;
  941.  
  942.     if(glyph == NULL) {
  943.         if((glyph = (byte *)malloc(INIT_GLYPH_SIZE)) == NULL)
  944.             return e_VMerror;
  945.         glyph_size = INIT_GLYPH_SIZE;
  946.     }
  947.  
  948.     /* scan glyph index */
  949.     for(idx = 0; idx < pi->num_glyphs; idx++ ) {
  950.         if(pi->gi[idx].cc == cc)
  951.             break;
  952.     }
  953.     if(idx == pi->num_glyphs)
  954.         return 0;
  955.  
  956.     /* seek to the glyph */
  957.     if(fseek(fp, pi->gi[idx].offset, 0) < 0)
  958.         return e_ioerror;
  959.  
  960.     /* read glyph data */
  961.     if(read_glyph_data(fp, data) < 0)
  962.         return e_ioerror;
  963.  
  964.     /* check the length of bitmap */
  965.     if(((data->w - 1) / 8 + 1) * data->h > length)
  966.         return e_limitcheck;
  967.  
  968.     /* reallocate glyph buffer */
  969.     if(glyph_size < data->rs) {
  970.         int size = glyph_size;
  971.         while(size < data->rs)
  972.             size *= 2;
  973.         free(glyph);
  974.         if((glyph = (byte *)malloc(size)) == NULL)
  975.             return e_VMerror;
  976.         glyph_size = size;
  977.     }
  978.  
  979. #ifdef DEBUG
  980.     fprintf(stderr, "cc: %02X, offset: %08X, w: %d, h: %d\n",
  981.         data->cc, pi->gi[idx].offset, data->w, data->h);
  982.     fprintf(stderr, "ftell(fp): %08X\n", ftell(fp));
  983. #endif
  984.     /* read glyph */
  985.     if(fread(glyph, 1, data->rs, fp) != data->rs)
  986.         return e_ioerror;
  987.     
  988.     /* convert glyph to bitmap */
  989.     if(glyph_to_bitmap(data, glyph, bitmap) < 0)
  990.         return e_ioerror;
  991.  
  992.     return 1;
  993. }
  994.  
  995. /* -------- JTeX PK Font File Routines -------- */
  996.  
  997. #define SERIAL(jis_code) \
  998.     (((jis_code) >> 8) * 94 + ((jis_code) & 0xff) - 0x21)
  999.  
  1000. /* JTeX PK File Name */
  1001.  
  1002. private int
  1003. jtex_pk_file_name(char *file_name, int jis_code, char **pk_file_name)
  1004. {
  1005.     char *ptr, *bp, *tail;
  1006.     int length = strlen(file_name);
  1007.     static char *buffer = NULL;
  1008.     static int buffer_size = 0;
  1009.     static int russian = 7;    /* strlen("russian") */
  1010.  
  1011.     if(buffer == NULL) {
  1012.         buffer_size = (length + russian) * 2;
  1013.         if((buffer = (char *)malloc(buffer_size)) == NULL)
  1014.             return e_VMerror;
  1015.     }
  1016.     else if(buffer_size < length + russian) {
  1017.         buffer_size = (length + russian) * 2;
  1018.         if((buffer = (char *)realloc(buffer, buffer_size)) == NULL)
  1019.             return e_VMerror;
  1020.     }
  1021.  
  1022.     for(ptr = file_name + length - 1; ptr >= file_name; ptr --) {
  1023.         if(*ptr == '\\') {
  1024.             strcpy(buffer, file_name);
  1025.             bp = buffer + (ptr - file_name);
  1026.             *bp = 0;
  1027.             tail = ptr + 1;
  1028.             break;
  1029.         }
  1030.     }
  1031.     if(ptr < file_name)
  1032.         return e_rangecheck;
  1033.  
  1034.     if(jis_code < 0x2100)
  1035.         return e_rangecheck;
  1036.     else if(jis_code < 0x2300)
  1037.         strcpy(bp, "sy");
  1038.     else if(jis_code < 0x2400)
  1039.         strcpy(bp, "roma");
  1040.     else if(jis_code < 0x2500)
  1041.         strcpy(bp, "hira");
  1042.     else if(jis_code < 0x2600)
  1043.         strcpy(bp, "kata");
  1044.     else if(jis_code < 0x2700)
  1045.         strcpy(bp, "greek");
  1046.     else if(jis_code < 0x2800)
  1047.         strcpy(bp, "russian");
  1048.     else if(jis_code < 0x2900)
  1049.         strcpy(bp, "keisen");
  1050.     else if(jis_code < 0x3000)
  1051.         return e_rangecheck;
  1052.     else if(jis_code < 0x5000) {
  1053.         int c = 'a' + (SERIAL(jis_code) - SERIAL(0x3021)) / 256;
  1054.         sprintf(bp, "k%c", c);
  1055.     }
  1056.     else if(jis_code < 0x8000) {
  1057.         int c = 'm' + (SERIAL(jis_code) - SERIAL(0x5021)) / 256;
  1058.         sprintf(bp, "k%c", c);
  1059.     }
  1060.     else
  1061.         return e_rangecheck;
  1062.  
  1063.     strcat(buffer, tail);
  1064.     *pk_file_name = buffer;
  1065.  
  1066.     return 0;
  1067. }
  1068.  
  1069. /*
  1070.  * JTeX PK Character Code
  1071.  */
  1072.  
  1073. private int
  1074. jtex_pk_char_code(int jis_code)
  1075. {
  1076.     if(jis_code < 0x2100)
  1077.         return e_rangecheck;
  1078.     else if(jis_code < 0x2200)
  1079.         return SERIAL(jis_code) - SERIAL(0x2120);
  1080.     else if(jis_code < 0x2300)
  1081.         return SERIAL(jis_code) - SERIAL(0x2220) + 100;
  1082.     else if(jis_code < 0x2400)
  1083.         return SERIAL(jis_code) - SERIAL(0x2300);
  1084.     else if(jis_code < 0x2500)
  1085.         return SERIAL(jis_code) - SERIAL(0x2420);
  1086.     else if(jis_code < 0x2600)
  1087.         return SERIAL(jis_code) - SERIAL(0x2520);
  1088.     else if(jis_code < 0x2700)
  1089.         return SERIAL(jis_code) - SERIAL(0x2620);
  1090.     else if(jis_code < 0x2800)
  1091.         return SERIAL(jis_code) - SERIAL(0x2720);
  1092.     else if(jis_code < 0x2900)
  1093.         return SERIAL(jis_code) - SERIAL(0x2820);
  1094.     else if(jis_code < 0x3000)
  1095.         return e_rangecheck;
  1096.     else if(jis_code < 0x5000)
  1097.         return (SERIAL(jis_code) - SERIAL(0x3021)) % 256;
  1098.     else if(jis_code < 0x8000)
  1099.         return (SERIAL(jis_code) - SERIAL(0x5021)) % 256;
  1100.     else
  1101.         return e_rangecheck;
  1102. }
  1103.  
  1104. /*
  1105.  * JTeX PK bitmap
  1106.  */
  1107.  
  1108. private int
  1109. jtex_pk_bitmap(char *file, int jis_code,
  1110.            int *width, int *height, byte *bitmap, int length,
  1111.            floatp *ds, floatp *hppp, floatp *vppp, 
  1112.            floatp *tfm, floatp *dx, floatp *dy, int *hoff, int *voff)
  1113. {
  1114.     char *pk_file_name;
  1115.     int code;
  1116.     ulong cc;
  1117.     pk_file pf;
  1118.     glyph_data data;
  1119.  
  1120.     if((code = jtex_pk_file_name(file, jis_code, &pk_file_name)) < 0)
  1121.         return code;
  1122. #ifdef DEBUG
  1123.     fprintf(stderr, "pk_file_name: %s\n", pk_file_name);
  1124. #endif
  1125.     if((code = open_pk_file(pk_file_name, &pf)) < 0) {
  1126.         fprintf(stderr, 
  1127.             "jtex_pk_bitmap: cannot open `%s'.\n", pk_file_name);
  1128.         return e_undefinedfilename;
  1129.     }
  1130. #ifdef DEBUG
  1131.     {
  1132.         int idx;
  1133.         idx = fp_cache.head;
  1134.         do {
  1135.             fprintf(stderr, "%d ", fp_cache.item[idx].id);
  1136.         } while((idx = fp_cache.item[idx].next) != fp_cache.head);
  1137.         fprintf(stderr, "\n");
  1138.     }
  1139. #endif
  1140.     if((cc = jtex_pk_char_code(jis_code)) < 0)
  1141.         return e_rangecheck;
  1142.  
  1143.     if((code = read_pk_bitmap(&pf, cc, &data, bitmap, length)) < 0)
  1144.         return code;
  1145.  
  1146.     if(code == 0) {
  1147.         /* undefined character */
  1148.  
  1149.         *width = 0;
  1150.         *height = 0;
  1151.         
  1152.         *ds = pf.pi.pa.ds;
  1153.         *hppp = pf.pi.pa.hppp;
  1154.         *vppp = pf.pi.pa.vppp;
  1155.  
  1156.         *tfm = 0;
  1157.         *dx = 0;
  1158.         *dy = 0;
  1159.         *hoff = 0;
  1160.         *voff = 0;
  1161.  
  1162.         return 0;
  1163.     }
  1164.  
  1165.     *width = data.w;
  1166.     *height = data.h;
  1167.  
  1168.     *ds = pf.pi.pa.ds;
  1169.     *hppp = pf.pi.pa.hppp;
  1170.     *vppp = pf.pi.pa.vppp;
  1171.  
  1172.     *tfm = data.tfm;
  1173.     *dx = data.dx;
  1174.     *dy = data.dy;
  1175.     *hoff = data.hoff;
  1176.     *voff = data.voff;
  1177.     
  1178. #ifdef DEBUG
  1179.     {
  1180.         int x, y, w8 = (data.w - 1) / 8 + 1;
  1181.         for(y=0; y<data.h; y++) {
  1182.             for(x=0; x<data.w; x++) {
  1183.                 if(bitmap[x/8 + w8*y] & (0x80 >> (x % 8)))
  1184.                     fprintf(stderr, "*");
  1185.                 else
  1186.                     fprintf(stderr, " ");
  1187.             }
  1188.             fprintf(stderr, "\n");
  1189.         }
  1190.     }
  1191. #endif
  1192.     return 0;
  1193. }
  1194.            
  1195. /* -------- Ghostscript Image Routines -------- */
  1196.  
  1197. /*
  1198.  * JTeX Kanji width
  1199.  */
  1200.  
  1201. #define INIT_KANJI_WIDTH_CACHE_SIZE    32
  1202.  
  1203. #define DUMMY_KANJI_CODE    0x3021
  1204. #define DUMMY_BITMAP_SIZE    10000
  1205.  
  1206. private int
  1207. jtex_kanji_width(char *file, floatp *kanji_width)
  1208. {
  1209.     int id;
  1210.     static floatp *cache = NULL;
  1211.     static int cache_size;
  1212.  
  1213.     if(cache == NULL) {
  1214.         int size = INIT_KANJI_WIDTH_CACHE_SIZE;
  1215.         if((cache = (floatp *)malloc(sizeof(floatp)*size)) == NULL)
  1216.             return e_VMerror;
  1217.         memset(cache, 0, sizeof(floatp)*size);
  1218.         cache_size = size;
  1219.     }
  1220.  
  1221.     if((id = file_name_id(file)) < 0)
  1222.         return e_undefinedfilename;
  1223.     
  1224.     if(id >= cache_size) {
  1225.         int size = cache_size;
  1226.         while(id >= size)
  1227.             size *= 2;
  1228.         if((cache = (floatp *)
  1229.             realloc(cache, sizeof(floatp)*size)) == NULL)
  1230.             return e_VMerror;
  1231.         memset(cache + cache_size, 0,
  1232.                sizeof(floatp)*(size - cache_size));
  1233.         cache_size = size;
  1234.     }
  1235.         
  1236.     if(cache[id] == 0) {
  1237.         int width, height;
  1238.         byte bitmap[DUMMY_BITMAP_SIZE];
  1239.         int length = DUMMY_BITMAP_SIZE;
  1240.         floatp ds, hppp, vppp, tfm, dx, dy;
  1241.         int hoff, voff;
  1242.         int code;
  1243.  
  1244.         if((code = jtex_pk_bitmap(file, DUMMY_KANJI_CODE,
  1245.                       &width, &height, bitmap, length,
  1246.                       &ds, &hppp, &vppp,
  1247.                       &tfm, &dx, &dy, &hoff, &voff)) < 0)
  1248.             return code;
  1249.  
  1250.         cache[id] = dx;
  1251.     }
  1252.  
  1253.     *kanji_width = cache[id];
  1254.     return 0;
  1255. }
  1256.  
  1257. /*
  1258.  * Retrieve Font Image
  1259.  */
  1260.  
  1261. private int
  1262. jteximage(char *file, int jis_code, 
  1263.       int *width, int *height, byte *bitmap, int length, 
  1264.       gs_matrix *pmat, floatp *wx, floatp *wy)
  1265. {
  1266.     int code;
  1267.     floatp ds, hppp, vppp, tfm, dx, dy;
  1268.     int hoff, voff;
  1269.  
  1270.     floatp kanji_width;
  1271.     floatp scale, tx, ty;
  1272.     gs_matrix smat, tmat;
  1273.  
  1274.     if((code = jtex_pk_bitmap(file, jis_code, 
  1275.                   width, height, bitmap, length,
  1276.                   &ds, &hppp, &vppp, 
  1277.                   &tfm, &dx, &dy, &hoff, &voff)) < 0)
  1278.         return code;
  1279. #ifdef DEBUG
  1280.     fprintf(stderr, "ds : %g, hppp: %g, vppp: %g\n", ds, hppp, vppp);
  1281.     fprintf(stderr, "tfm: %g, dx : %g, dy : %g, hoff: %d, voff : %d\n",
  1282.         tfm, dx, dy, hoff, voff);
  1283. #endif
  1284.     /* Retrieve Kanji Width */
  1285.  
  1286.     if((code = jtex_kanji_width(file, &kanji_width)) < 0)
  1287.         return code; 
  1288.  
  1289.     /* Transform Image */
  1290.  
  1291.     gs_make_identity(pmat);
  1292.  
  1293.     scale = (floatp)B_X_EX / kanji_width;
  1294.     gs_make_scaling(1.0 / scale, -1.0 / scale, &smat);
  1295.  
  1296.     tx = hoff + dx / 2.0 - (floatp)B_X_CL / scale;
  1297.     ty = voff + (floatp)B_Y_RP / scale;
  1298.     gs_make_translation(tx, ty, &tmat);
  1299.  
  1300.     gs_matrix_multiply(pmat, &smat, pmat);
  1301.     gs_matrix_multiply(pmat, &tmat, pmat);
  1302.  
  1303.     *wx = (floatp)B_X_CL * 2.0;
  1304.     *wy = 0;
  1305.  
  1306.     return 0;
  1307. }
  1308.