home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / unixtex-6.1b-src.tgz / tar.out / contrib / unixtex / xdvik / gf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-28  |  8.4 KB  |  334 lines

  1. /*
  2.  * Copyright (c) 1994 Paul Vojta.  All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions
  6.  * are met:
  7.  * 1. Redistributions of source code must retain the above copyright
  8.  *    notice, this list of conditions and the following disclaimer.
  9.  * 2. Redistributions in binary form must reproduce the above copyright
  10.  *    notice, this list of conditions and the following disclaimer in the
  11.  *    documentation and/or other materials provided with the distribution.
  12.  *
  13.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  14.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  16.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  17.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  19.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  20.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  23.  * SUCH DAMAGE.
  24.  */
  25.  
  26. #include "config.h"
  27.  
  28. /***
  29.  ***    GF font reading routines.
  30.  ***    Public routines are read_GF_index and read_GF_char.
  31.  ***/
  32.  
  33. #define    PAINT_0        0
  34. #define    PAINT1        64
  35. #define    PAINT2        65
  36. #define    PAINT3        66
  37. #define    BOC        67
  38. #define    BOC1        68
  39. #define    EOC        69
  40. #define    SKIP0        70
  41. #define    SKIP1        71
  42. #define    SKIP2        72
  43. #define    SKIP3        73
  44. #define    NEW_ROW_0    74
  45. #define    NEW_ROW_MAX    238
  46. #define    XXX1        239
  47. #define    XXX2        240
  48. #define    XXX3        241
  49. #define    XXX4        242
  50. #define    YYY        243
  51. #define    NO_OP        244
  52. #define    CHAR_LOC    245
  53. #define    CHAR_LOC0    246
  54. #define    PRE        247
  55. #define    POST        248
  56. #define    POST_POST    249
  57.  
  58. #define    GF_ID_BYTE    131
  59. #define    TRAILER        223        /* Trailing bytes at end of file */
  60.  
  61. static    FILE    *GF_file;
  62.  
  63. static    void
  64. expect(ch)
  65.     ubyte ch;
  66. {
  67.     ubyte ch1 = one(GF_file);
  68.  
  69.     if (ch1 != ch)
  70.         oops("Bad GF file:  %d expected, %d received.", ch, ch1);
  71. }
  72.  
  73. static    void
  74. too_many_bits(ch)
  75.     ubyte ch;
  76. {
  77.     oops("Too many bits found when loading character %d", ch);
  78. }
  79.  
  80. /*
  81.  *    Public routines
  82.  */
  83.  
  84.  
  85. static    void
  86. #if    NeedFunctionPrototypes
  87. read_GF_char(register struct font *fontp, wide_ubyte ch)
  88. #else    /* !NeedFunctionPrototypes */
  89. read_GF_char(fontp, ch)
  90.     register struct font *fontp;
  91.     ubyte    ch;
  92. #endif    /* NeedFunctionPrototypes */
  93. {
  94.     register struct glyph *g;
  95.     ubyte    cmnd;
  96.     int    min_m, max_m, min_n, max_n;
  97.     BMUNIT    *cp, *basep, *maxp;
  98.     int    bytes_wide;
  99.     Boolean    paint_switch;
  100. #define    White    False
  101. #define    Black    True
  102.     Boolean    new_row;
  103.     int    count;
  104.     int    word_weight;
  105.  
  106.     g = &fontp->glyph[ch];
  107.     GF_file = fontp->file;
  108.  
  109.     if(debug & DBG_PK)
  110.         Printf("Loading gf char %d", ch);
  111.  
  112.     for (;;) {
  113.         switch (cmnd = one(GF_file)) {
  114.         case XXX1:
  115.         case XXX2:
  116.         case XXX3:
  117.         case XXX4:
  118.             Fseek(GF_file, (long) num(GF_file,
  119.             WIDENINT cmnd - XXX1 + 1), 1);
  120.             continue;
  121.         case YYY:
  122.             (void) four(GF_file);
  123.             continue;
  124.         case BOC:
  125.             (void) four(GF_file);    /* skip character code */
  126.             (void) four(GF_file);    /* skip pointer to prev char */
  127.             min_m = sfour(GF_file);
  128.             max_m = sfour(GF_file);
  129.             g->x = -min_m;
  130.             min_n = sfour(GF_file);
  131.             g->y = max_n = sfour(GF_file);
  132.             g->bitmap.w = max_m - min_m + 1;
  133.             g->bitmap.h = max_n - min_n + 1;
  134.             break;
  135.         case BOC1:
  136.             (void) one(GF_file);    /* skip character code */
  137.             g->bitmap.w = one(GF_file);    /* max_m - min_m */
  138.             g->x = g->bitmap.w - one(GF_file);    /* ditto - max_m */
  139.             ++g->bitmap.w;
  140.             g->bitmap.h = one(GF_file) + 1;
  141.             g->y = one(GF_file);
  142.             break;
  143.         default:
  144.             oops("Bad BOC code:  %d", cmnd);
  145.         }
  146.         break;
  147.     }
  148.     paint_switch = White;
  149.  
  150.     if (debug & DBG_PK)
  151.         Printf(", size=%dx%d, dvi_adv=%ld\n", g->bitmap.w, g->bitmap.h,
  152.         g->dvi_adv);
  153.  
  154.     alloc_bitmap(&g->bitmap);
  155.     cp = basep = (BMUNIT *) g->bitmap.bits;
  156. /*
  157.  *    Read character data into *basep
  158.  */
  159.     bytes_wide = ROUNDUP((int) g->bitmap.w, BITS_PER_BMUNIT)
  160.         * BYTES_PER_BMUNIT;
  161.     maxp = ADD(basep, g->bitmap.h * bytes_wide);
  162.     bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
  163.     new_row = False;
  164.     word_weight = BITS_PER_BMUNIT;
  165.     for (;;) {
  166.         count = -1;
  167.         cmnd = one(GF_file);
  168.         if (cmnd < 64) count = cmnd;
  169.         else if (cmnd >= NEW_ROW_0 && cmnd <= NEW_ROW_MAX) {
  170.         count = cmnd - NEW_ROW_0;
  171.         paint_switch = White;    /* it'll be complemented later */
  172.         new_row = True;
  173.         }
  174.         else switch (cmnd) {
  175.         case PAINT1:
  176.         case PAINT2:
  177.         case PAINT3:
  178.             count = num(GF_file, WIDENINT cmnd - PAINT1 + 1);
  179.             break;
  180.         case EOC:
  181.             if (cp >= ADD(basep, bytes_wide)) too_many_bits(ch);
  182.             return;
  183.         case SKIP1:
  184.         case SKIP2:
  185.         case SKIP3:
  186.             *((char **) &basep) +=
  187.             num(GF_file, WIDENINT cmnd - SKIP0) * bytes_wide;
  188.         case SKIP0:
  189.             new_row = True;
  190.             paint_switch = White;
  191.             break;
  192.         case XXX1:
  193.         case XXX2:
  194.         case XXX3:
  195.         case XXX4:
  196.             Fseek(GF_file, (long) num(GF_file,
  197.             WIDENINT cmnd - XXX1 + 1), 1);
  198.             break;
  199.         case YYY:
  200.             (void) four(GF_file);
  201.             break;
  202.         case NO_OP:
  203.             break;
  204.         default:
  205.             oops("Bad command in GF file:  %d", cmnd);
  206.         } /* end switch */
  207.         if (new_row) {
  208.         *((char **) &basep) += bytes_wide;
  209.         if (basep >= maxp || cp >= basep) too_many_bits(ch);
  210.         cp = basep;
  211.         word_weight = BITS_PER_BMUNIT;
  212.         new_row = False;
  213.         }
  214.         if (count >= 0) {
  215.         while (count)
  216.             if (count <= word_weight) {
  217. #ifndef    MSBITFIRST
  218.             if (paint_switch)
  219.                 *cp |= bit_masks[count] <<
  220.                 (BITS_PER_BMUNIT - word_weight);
  221. #endif
  222.             word_weight -= count;
  223. #ifdef    MSBITFIRST
  224.             if (paint_switch)
  225.                 *cp |= bit_masks[count] << word_weight;
  226. #endif
  227.             break;
  228.             }
  229.             else {
  230.             if (paint_switch)
  231. #ifndef    MSBITFIRST
  232.                 *cp |= bit_masks[word_weight] <<
  233.                 (BITS_PER_BMUNIT - word_weight);
  234. #else
  235.                 *cp |= bit_masks[word_weight];
  236. #endif
  237.             cp++;
  238.             count -= word_weight;
  239.             word_weight = BITS_PER_BMUNIT;
  240.             }
  241.         paint_switch = 1 - paint_switch;
  242.         }
  243.     } /* end for */
  244. }
  245.  
  246.  
  247. void
  248. read_GF_index(fontp, hushcs)
  249.     register struct font    *fontp;
  250.     wide_bool        hushcs;
  251. {
  252.     int    hppp, vppp;
  253.     ubyte    ch, cmnd;
  254.     register struct glyph *g;
  255.     long    checksum;
  256.  
  257.     fontp->read_char = read_GF_char;
  258.     GF_file = fontp->file;
  259.     if (debug & DBG_PK)
  260.         Printf("Reading GF pixel file %s\n", fontp->filename);
  261. /*
  262.  *    Find postamble.
  263.  */
  264.     Fseek(GF_file, (long) -4, 2);
  265.     while (four(GF_file) != ((unsigned long) TRAILER << 24 | TRAILER << 16
  266.         | TRAILER << 8 | TRAILER))
  267.         Fseek(GF_file, (long) -5, 1);
  268.     Fseek(GF_file, (long) -5, 1);
  269.     for (;;) {
  270.         ch = one(GF_file);
  271.         if (ch != TRAILER) break;
  272.         Fseek(GF_file, (long) -2, 1);
  273.     }
  274.     if (ch != GF_ID_BYTE) oops("Bad end of font file %s", fontp->fontname);
  275.     Fseek(GF_file, (long) -6, 1);
  276.     expect(POST_POST);
  277.     Fseek(GF_file, sfour(GF_file), 0);    /* move to postamble */
  278. /*
  279.  *    Read postamble.
  280.  */
  281.     expect(POST);
  282.     (void) four(GF_file);        /* pointer to last eoc + 1 */
  283.     (void) four(GF_file);        /* skip design size */
  284.     checksum = four(GF_file);
  285.     if (!hushcs && checksum && fontp->checksum
  286.             && checksum != fontp->checksum)
  287.         Fprintf(stderr,
  288.         "Checksum mismatch (dvi = %lu, gf = %lu) in font file %s\n",
  289.         fontp->checksum, checksum, fontp->filename);
  290.     hppp = sfour(GF_file);
  291.     vppp = sfour(GF_file);
  292.     if (hppp != vppp && (debug & DBG_PK))
  293.         Printf("Font has non-square aspect ratio %d:%d\n", vppp, hppp);
  294.     (void) four(GF_file);        /* skip min_m */
  295.     (void) four(GF_file);        /* skip max_m */
  296.     (void) four(GF_file);        /* skip min_n */
  297.     (void) four(GF_file);        /* skip max_n */
  298. /*
  299.  *    Prepare glyph array.
  300.  */
  301.     fontp->glyph = (struct glyph *) xmalloc(256 * sizeof(struct glyph),
  302.         "glyph array");
  303.     bzero((char *) fontp->glyph, 256 * sizeof(struct glyph));
  304. /*
  305.  *    Read glyph directory.
  306.  */
  307.     while ((cmnd = one(GF_file)) != POST_POST) {
  308.         int addr;
  309.  
  310.         ch = one(GF_file);            /* character code */
  311.         g = &fontp->glyph[ch];
  312.         switch (cmnd) {
  313.         case CHAR_LOC:
  314.             /* g->pxl_adv = sfour(GF_file); */
  315.             (void) four(GF_file);
  316.             (void) four(GF_file);    /* skip dy */
  317.             break;
  318.         case CHAR_LOC0:
  319.             /* g->pxl_adv = one(GF_file) << 16; */
  320.             (void) one(GF_file);
  321.             break;
  322.         default:
  323.             oops("Non-char_loc command found in GF preamble:  %d",
  324.             cmnd);
  325.         }
  326.         g->dvi_adv = fontp->dimconv * sfour(GF_file);
  327.         addr = four(GF_file);
  328.         if (addr != -1) g->addr = addr;
  329.         if (debug & DBG_PK)
  330.         Printf("Read GF glyph for character %d; dy = %ld, addr = %x\n",
  331.             ch, g->dvi_adv, addr);
  332.     }
  333. }
  334.