home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume3 / xdvi / part03 / gf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-07  |  6.5 KB  |  293 lines

  1. #include <stdio.h>
  2. #include "xdvi.h"
  3.  
  4. /***
  5.  ***    GF font reading routines.
  6.  ***    Public routines are read_index and read_char.
  7.  ***/
  8.  
  9. static    void    read_index(), read_char();
  10.  
  11. read_font_index_proc    read_GF_index    = read_index;
  12.  
  13. #define    PAINT_0        0
  14. #define    PAINT1        64
  15. #define    PAINT2        65
  16. #define    PAINT3        66
  17. #define    BOC        67
  18. #define    BOC1        68
  19. #define    EOC        69
  20. #define    SKIP0        70
  21. #define    SKIP1        71
  22. #define    SKIP2        72
  23. #define    SKIP3        73
  24. #define    NEW_ROW_0    74
  25. #define    NEW_ROW_MAX    238
  26. #define    XXX1        239
  27. #define    XXX2        240
  28. #define    XXX3        241
  29. #define    XXX4        242
  30. #define    YYY        243
  31. #define    NO_OP        244
  32. #define    CHAR_LOC    245
  33. #define    CHAR_LOC0    246
  34. #define    PRE        247
  35. #define    POST        248
  36. #define    POST_POST    249
  37.  
  38. #define    GF_ID_BYTE    131
  39. #define    TRAILER        223        /* Trailing bytes at end of file */
  40.  
  41. static    FILE    *GF_file;
  42.  
  43. static    void
  44. expect(ch)
  45.     ubyte ch;
  46. {
  47.     ubyte ch1 = one(GF_file);
  48.  
  49.     if (ch1 != ch)
  50.         oops("Bad GF file:  %d expected, %d received.", ch, ch1);
  51. }
  52.  
  53. static    void
  54. too_many_bits(ch)
  55.     ubyte ch;
  56. {
  57.     oops("Too many bits found when loading character %d", ch);
  58. }
  59.  
  60. /*
  61.  *    Public routines
  62.  */
  63.  
  64. static    void
  65. read_index(fontp)
  66.     register struct font *fontp;
  67. {
  68.     int    hppp, vppp;
  69.     ubyte    ch, cmnd;
  70.     register struct glyph *g;
  71.  
  72.     fontp->read_char = read_char;
  73.     GF_file = fontp->file;
  74. /*
  75.  *    Read the preamble.
  76.  */
  77.     if (debug & DBG_PK)
  78.         Printf("Reading header for GF pixel file %s\n", fontp->filename);
  79.     GF_file = fontp->file;
  80.     expect(PRE);
  81.     expect(GF_ID_BYTE);
  82. /*
  83.  *    Find postamble.
  84.  */
  85.     Fseek(GF_file, (long) -5, 2);
  86.     for (;;) {
  87.         ch = one(GF_file);
  88.         if (ch != TRAILER) break;
  89.         Fseek(GF_file, (long) -2, 1);
  90.     }
  91.     if (ch != GF_ID_BYTE) oops("Bad end of font file %s", fontp->fontname);
  92.     Fseek(GF_file, (long) -6, 1);
  93.     expect(POST_POST);
  94.     Fseek(GF_file, sfour(GF_file), 0);    /* move to postamble */
  95. /*
  96.  *    Read postamble.
  97.  */
  98.     expect(POST);
  99.     (void) four(GF_file);    /* pointer to last eoc + 1 */
  100.     (void) four(fontp->file);        /* skip design size */
  101.     (void) four(fontp->file);        /* skip checksum */
  102.     hppp = sfour(fontp->file);
  103.     vppp = sfour(fontp->file);
  104.     if (debug && hppp != vppp)
  105.         oops("Warning: aspect ratio not 1:1 for font %s", fontp->fontname);
  106.     (void) four(fontp->file);        /* skip min_m */
  107.     (void) four(fontp->file);        /* skip max_m */
  108.     (void) four(fontp->file);        /* skip min_n */
  109.     (void) four(fontp->file);        /* skip max_n */
  110. /*
  111.  *    Prepare glyph array.
  112.  */
  113.     for (g = fontp->glyph; g < &fontp->glyph[MAXCHARS]; ++g) {
  114.         g->addr = 0;
  115.         g->bitmap.bits = NULL;
  116.         g->bitmap2.bits = NULL;
  117.     }
  118. /*
  119.  *    Read glyph directory.
  120.  */
  121.     while ((cmnd = one(GF_file)) != POST_POST) {
  122.         ubyte ch;
  123.         int addr;
  124.  
  125.         ch = one(GF_file);            /* character code */
  126.         if (ch >= MAXCHARS)
  127.         oops("Character code %d outside range, file %s", ch,
  128.             fontp->fontname);
  129.         g = &fontp->glyph[ch];
  130.         switch (cmnd) {
  131.         case CHAR_LOC:
  132.             g->dvi_adv = sfour(GF_file);
  133.             (void) four(GF_file);    /* skip dy */
  134.             break;
  135.         case CHAR_LOC0:
  136.             g->dvi_adv = one(GF_file) << 16;
  137.             break;
  138.         default:
  139.             oops("Non-char_loc command found in GF preamble:  %d",
  140.             cmnd);
  141.         }
  142.         (void) four(GF_file);        /* skip width */
  143.         addr = four(GF_file);
  144.         if (addr != -1) g->addr = addr;
  145.         if (debug & DBG_PK)
  146.         Printf("Read GF glyph for character %d; dy = %d, addr = %d\n",
  147.             ch, g->dvi_adv, addr);
  148.     }
  149. }
  150.  
  151.  
  152. static    void
  153. read_char(fontp, ch)
  154.     register struct font *fontp;
  155.     ubyte ch;
  156. {
  157.     register struct glyph *g;
  158.     ubyte    cmnd;
  159.     int    min_m, max_m, min_n, max_n;
  160.     BMUNIT    *cp, *basep, *maxp;
  161.     int    bytes_wide;
  162.     Boolean    paint_switch;
  163. #define    White    False
  164. #define    Black    True
  165.     Boolean    new_row;
  166.     int    count;
  167.     int    word_weight;
  168.  
  169.     g = &fontp->glyph[ch];
  170.     GF_file = fontp->file;
  171.  
  172.     if(debug & DBG_PK)
  173.         Printf("Loading gf char %d", ch);
  174.  
  175.     switch (cmnd = one(GF_file)) {
  176.         case BOC:
  177.         (void) four(GF_file);        /* skip character code */
  178.         (void) four(GF_file);        /* skip pointer to prev char */
  179.         min_m = sfour(GF_file);
  180.         max_m = sfour(GF_file);
  181.         g->x = -min_m;
  182.         min_n = sfour(GF_file);
  183.         g->y = max_n = sfour(GF_file);
  184.         g->bitmap.w = max_m - min_m + 1;
  185.         g->bitmap.h = max_n - min_n + 1;
  186.         break;
  187.         case BOC1:
  188.         (void) one(GF_file);        /* skip character code */
  189.         g->bitmap.w = one(GF_file);    /* max_m - min_m */
  190.         g->x = g->bitmap.w - one(GF_file);    /* ditto - max_m */
  191.         ++g->bitmap.w;
  192.         g->bitmap.h = one(GF_file) + 1;
  193.         g->y = one(GF_file);
  194.         break;
  195.         default:
  196.         oops("Bad BOC code:  %d", cmnd);
  197.     }
  198.     paint_switch = White;
  199.  
  200.     if (debug & DBG_PK)
  201.         Printf(", size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
  202.         g->dvi_adv);
  203.  
  204.     alloc_bitmap(&g->bitmap, fontp->fontname, ch);
  205.     cp = basep = (BMUNIT *) g->bitmap.bits;
  206. /*
  207.  *    Read character data into *basep
  208.  */
  209.     bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
  210.     maxp = ADD(basep, g->bitmap.h * bytes_wide);
  211.         bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
  212.     new_row = False;
  213.     word_weight = BITS_PER_BMUNIT;
  214.     for (;;) {
  215.         count = -1;
  216.         cmnd = one(GF_file);
  217.         if (cmnd < 64) count = cmnd;
  218.         else if (cmnd >= NEW_ROW_0 && cmnd <= NEW_ROW_MAX) {
  219.         count = cmnd - NEW_ROW_0;
  220.         paint_switch = White;    /* it'll be complemented later */
  221.         new_row = True;
  222.         }
  223.         else switch (cmnd) {
  224.         case PAINT1:
  225.         case PAINT2:
  226.         case PAINT3:
  227.             count = num(GF_file, cmnd - PAINT1 + 1);
  228.             break;
  229.         case EOC:
  230.             if (cp >= ADD(basep, bytes_wide)) too_many_bits(ch);
  231.             return;
  232.         case SKIP1:
  233.         case SKIP2:
  234.         case SKIP3:
  235.             *((char **) &basep) +=
  236.             num(GF_file, cmnd - SKIP0) * bytes_wide;
  237.         case SKIP0:
  238.             new_row = True;
  239.             paint_switch = White;
  240.             break;
  241.         case XXX1:
  242.         case XXX2:
  243.         case XXX3:
  244.         case XXX4:
  245.             Fseek(GF_file, (long) num(GF_file, cmnd - XXX1 + 1), 1);
  246.             break;
  247.         case YYY:
  248.             (void) four(GF_file);
  249.             break;
  250.         case NO_OP:
  251.             break;
  252.         default:
  253.             oops("Bad command in GF file:  %d", cmnd);
  254.         } /* end switch */
  255.         if (new_row) {
  256.         *((char **) &basep) += bytes_wide;
  257.         if (basep >= maxp || cp >= basep) too_many_bits(ch);
  258.         cp = basep;
  259.         word_weight = BITS_PER_BMUNIT;
  260.         new_row = False;
  261.         }
  262.         if (count >= 0) {
  263.         while (count)
  264.             if (count <= word_weight) {
  265. #ifndef    MSBITFIRST
  266.             if (paint_switch)
  267.                 *cp |= bit_masks[count] <<
  268.                 (BITS_PER_BMUNIT - word_weight);
  269. #endif    MSBITFIRST
  270.             word_weight -= count;
  271. #ifdef    MSBITFIRST
  272.             if (paint_switch)
  273.                 *cp |= bit_masks[count] << word_weight;
  274. #endif    MSBITFIRST
  275.             break;
  276.             }
  277.             else {
  278.             if (paint_switch)
  279. #ifndef    MSBITFIRST
  280.                 *cp |= bit_masks[word_weight] <<
  281.                 (BITS_PER_BMUNIT - word_weight);
  282. #else    MSBITFIRST
  283.                 *cp |= bit_masks[word_weight];
  284. #endif    MSBITFIRST
  285.             cp++;
  286.             count -= word_weight;
  287.             word_weight = BITS_PER_BMUNIT;
  288.             }
  289.         paint_switch = 1 - paint_switch;
  290.         }
  291.     } /* end for */
  292. }
  293.