home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include "xdvi.h"
-
- /***
- *** GF font reading routines.
- *** Public routines are read_index and read_char.
- ***/
-
- static void read_index(), read_char();
-
- read_font_index_proc read_GF_index = read_index;
-
- #define PAINT_0 0
- #define PAINT1 64
- #define PAINT2 65
- #define PAINT3 66
- #define BOC 67
- #define BOC1 68
- #define EOC 69
- #define SKIP0 70
- #define SKIP1 71
- #define SKIP2 72
- #define SKIP3 73
- #define NEW_ROW_0 74
- #define NEW_ROW_MAX 238
- #define XXX1 239
- #define XXX2 240
- #define XXX3 241
- #define XXX4 242
- #define YYY 243
- #define NO_OP 244
- #define CHAR_LOC 245
- #define CHAR_LOC0 246
- #define PRE 247
- #define POST 248
- #define POST_POST 249
-
- #define GF_ID_BYTE 131
- #define TRAILER 223 /* Trailing bytes at end of file */
-
- static FILE *GF_file;
-
- static void
- expect(ch)
- ubyte ch;
- {
- ubyte ch1 = one(GF_file);
-
- if (ch1 != ch)
- oops("Bad GF file: %d expected, %d received.", ch, ch1);
- }
-
- static void
- too_many_bits(ch)
- ubyte ch;
- {
- oops("Too many bits found when loading character %d", ch);
- }
-
- /*
- * Public routines
- */
-
- static void
- read_index(fontp)
- register struct font *fontp;
- {
- int hppp, vppp;
- ubyte ch, cmnd;
- register struct glyph *g;
-
- fontp->read_char = read_char;
- GF_file = fontp->file;
- /*
- * Read the preamble.
- */
- if (debug & DBG_PK)
- Printf("Reading header for GF pixel file %s\n", fontp->filename);
- GF_file = fontp->file;
- expect(PRE);
- expect(GF_ID_BYTE);
- /*
- * Find postamble.
- */
- Fseek(GF_file, (long) -5, 2);
- for (;;) {
- ch = one(GF_file);
- if (ch != TRAILER) break;
- Fseek(GF_file, (long) -2, 1);
- }
- if (ch != GF_ID_BYTE) oops("Bad end of font file %s", fontp->fontname);
- Fseek(GF_file, (long) -6, 1);
- expect(POST_POST);
- Fseek(GF_file, sfour(GF_file), 0); /* move to postamble */
- /*
- * Read postamble.
- */
- expect(POST);
- (void) four(GF_file); /* pointer to last eoc + 1 */
- (void) four(fontp->file); /* skip design size */
- (void) four(fontp->file); /* skip checksum */
- hppp = sfour(fontp->file);
- vppp = sfour(fontp->file);
- if (debug && hppp != vppp)
- oops("Warning: aspect ratio not 1:1 for font %s", fontp->fontname);
- (void) four(fontp->file); /* skip min_m */
- (void) four(fontp->file); /* skip max_m */
- (void) four(fontp->file); /* skip min_n */
- (void) four(fontp->file); /* skip max_n */
- /*
- * Prepare glyph array.
- */
- for (g = fontp->glyph; g < &fontp->glyph[MAXCHARS]; ++g) {
- g->addr = 0;
- g->bitmap.bits = NULL;
- g->bitmap2.bits = NULL;
- }
- /*
- * Read glyph directory.
- */
- while ((cmnd = one(GF_file)) != POST_POST) {
- ubyte ch;
- int addr;
-
- ch = one(GF_file); /* character code */
- if (ch >= MAXCHARS)
- oops("Character code %d outside range, file %s", ch,
- fontp->fontname);
- g = &fontp->glyph[ch];
- switch (cmnd) {
- case CHAR_LOC:
- g->dvi_adv = sfour(GF_file);
- (void) four(GF_file); /* skip dy */
- break;
- case CHAR_LOC0:
- g->dvi_adv = one(GF_file) << 16;
- break;
- default:
- oops("Non-char_loc command found in GF preamble: %d",
- cmnd);
- }
- (void) four(GF_file); /* skip width */
- addr = four(GF_file);
- if (addr != -1) g->addr = addr;
- if (debug & DBG_PK)
- Printf("Read GF glyph for character %d; dy = %d, addr = %d\n",
- ch, g->dvi_adv, addr);
- }
- }
-
-
- static void
- read_char(fontp, ch)
- register struct font *fontp;
- ubyte ch;
- {
- register struct glyph *g;
- ubyte cmnd;
- int min_m, max_m, min_n, max_n;
- BMUNIT *cp, *basep, *maxp;
- int bytes_wide;
- Boolean paint_switch;
- #define White False
- #define Black True
- Boolean new_row;
- int count;
- int word_weight;
-
- g = &fontp->glyph[ch];
- GF_file = fontp->file;
-
- if(debug & DBG_PK)
- Printf("Loading gf char %d", ch);
-
- switch (cmnd = one(GF_file)) {
- case BOC:
- (void) four(GF_file); /* skip character code */
- (void) four(GF_file); /* skip pointer to prev char */
- min_m = sfour(GF_file);
- max_m = sfour(GF_file);
- g->x = -min_m;
- min_n = sfour(GF_file);
- g->y = max_n = sfour(GF_file);
- g->bitmap.w = max_m - min_m + 1;
- g->bitmap.h = max_n - min_n + 1;
- break;
- case BOC1:
- (void) one(GF_file); /* skip character code */
- g->bitmap.w = one(GF_file); /* max_m - min_m */
- g->x = g->bitmap.w - one(GF_file); /* ditto - max_m */
- ++g->bitmap.w;
- g->bitmap.h = one(GF_file) + 1;
- g->y = one(GF_file);
- break;
- default:
- oops("Bad BOC code: %d", cmnd);
- }
- paint_switch = White;
-
- if (debug & DBG_PK)
- Printf(", size=%dx%d, dvi_adv=%d\n", g->bitmap.w, g->bitmap.h,
- g->dvi_adv);
-
- alloc_bitmap(&g->bitmap, fontp->fontname, ch);
- cp = basep = (BMUNIT *) g->bitmap.bits;
- /*
- * Read character data into *basep
- */
- bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT;
- maxp = ADD(basep, g->bitmap.h * bytes_wide);
- bzero(g->bitmap.bits, g->bitmap.h * bytes_wide);
- new_row = False;
- word_weight = BITS_PER_BMUNIT;
- for (;;) {
- count = -1;
- cmnd = one(GF_file);
- if (cmnd < 64) count = cmnd;
- else if (cmnd >= NEW_ROW_0 && cmnd <= NEW_ROW_MAX) {
- count = cmnd - NEW_ROW_0;
- paint_switch = White; /* it'll be complemented later */
- new_row = True;
- }
- else switch (cmnd) {
- case PAINT1:
- case PAINT2:
- case PAINT3:
- count = num(GF_file, cmnd - PAINT1 + 1);
- break;
- case EOC:
- if (cp >= ADD(basep, bytes_wide)) too_many_bits(ch);
- return;
- case SKIP1:
- case SKIP2:
- case SKIP3:
- *((char **) &basep) +=
- num(GF_file, cmnd - SKIP0) * bytes_wide;
- case SKIP0:
- new_row = True;
- paint_switch = White;
- break;
- case XXX1:
- case XXX2:
- case XXX3:
- case XXX4:
- Fseek(GF_file, (long) num(GF_file, cmnd - XXX1 + 1), 1);
- break;
- case YYY:
- (void) four(GF_file);
- break;
- case NO_OP:
- break;
- default:
- oops("Bad command in GF file: %d", cmnd);
- } /* end switch */
- if (new_row) {
- *((char **) &basep) += bytes_wide;
- if (basep >= maxp || cp >= basep) too_many_bits(ch);
- cp = basep;
- word_weight = BITS_PER_BMUNIT;
- new_row = False;
- }
- if (count >= 0) {
- while (count)
- if (count <= word_weight) {
- #ifndef MSBITFIRST
- if (paint_switch)
- *cp |= bit_masks[count] <<
- (BITS_PER_BMUNIT - word_weight);
- #endif MSBITFIRST
- word_weight -= count;
- #ifdef MSBITFIRST
- if (paint_switch)
- *cp |= bit_masks[count] << word_weight;
- #endif MSBITFIRST
- break;
- }
- else {
- if (paint_switch)
- #ifndef MSBITFIRST
- *cp |= bit_masks[word_weight] <<
- (BITS_PER_BMUNIT - word_weight);
- #else MSBITFIRST
- *cp |= bit_masks[word_weight];
- #endif MSBITFIRST
- cp++;
- count -= word_weight;
- word_weight = BITS_PER_BMUNIT;
- }
- paint_switch = 1 - paint_switch;
- }
- } /* end for */
- }
-