|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 8330 (0x208a) Types: TextFile Names: »pk.c«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« └─⟦ca79c7339⟧ └─⟦this⟧ »DVIware/crt-viewers/X/xdvi/pk.c«
#include <stdio.h> #include "xdvi.h" /*** *** PK font reading routines. *** Public routines are read_index and read_char. ***/ static void read_index(), read_char(); read_font_index_proc read_PK_index = read_index; #define PK_ID 89 #define PK_CMD_START 240 #define PK_X1 240 #define PK_X2 241 #define PK_X3 242 #define PK_X4 243 #define PK_Y 244 #define PK_POST 245 #define PK_NOOP 246 #define PK_PRE 247 static int PK_flag_byte; static unsigned PK_input_byte; static int PK_bitpos; static int PK_dyn_f; static int PK_repeat_count; static int PK_get_nyb( fp ) register FILE *fp; { unsigned temp; if( PK_bitpos < 0 ) { PK_input_byte = one(fp); PK_bitpos = 4; } temp = PK_input_byte >> PK_bitpos; PK_bitpos -= 4; return( temp & 0xf ); } static int PK_packed_num( fp ) register FILE *fp; { int i,j; if( ( i = PK_get_nyb( fp ) ) == 0 ) { do { j = PK_get_nyb( fp ); i++; } while( j == 0 ); while( i > 0 ) { j = (j << 4) + PK_get_nyb( fp ); i--; } return( j - 15 + ( (13 - PK_dyn_f) << 4 ) + PK_dyn_f ); } else { if( i <= PK_dyn_f ) return( i ); if( i < 14 ) return( ( (i - PK_dyn_f - 1) << 4 ) + PK_get_nyb( fp ) + PK_dyn_f + 1 ); if( i == 14 ) PK_repeat_count = PK_packed_num( fp ); else PK_repeat_count = 1; return( PK_packed_num( fp ) ); } } static void PK_skip_specials(fontp) register struct font *fontp; { int i,j; register FILE *fp = fontp->file; do { PK_flag_byte = one(fp); if( PK_flag_byte >= PK_CMD_START ) { switch( PK_flag_byte ) { case PK_X1 : case PK_X2 : case PK_X3 : case PK_X4 : { i = 0; for (j = PK_CMD_START; j <= PK_flag_byte; j++) i = (i*256) + one(fp); while (i--) (void) one(fp); break; } case PK_Y : (void) four(fp); case PK_POST : case PK_NOOP : break; default : oops("Unexpected %d in PK file %s", PK_flag_byte, fontp->fontname); break; } } } while( PK_flag_byte != PK_POST && PK_flag_byte >= PK_CMD_START ); } /** ** Public routines **/ static void read_index(fontp) register struct font *fontp; { int hppp, vppp; /* * Read the header of a packed pixel file. */ fontp->read_char = read_char; if (debug & DBG_PK) Printf("Reading header for PK pixel file %s\n", fontp->filename); if (one(fontp->file) != PK_PRE) oops("File %s lacks preamble command", fontp->fontname); if (one(fontp->file) != PK_ID) oops("File %s has wrong PK id", fontp->fontname); Fseek(fontp->file, (long) one(fontp->file), 1); /* skip comment */ (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); /*fontp->f_scale = (int)((((float) hppp * 72.27) / (float) 65536) + 0.5);*/ /*if (fontp->f_scale == 0) fontp->f_scale = 1000;*/ { register struct glyph *g; for (g = fontp->glyph; g < fontp->glyph + 256; ++g) { g->addr = 0; g->bitmap.bits = NULL; g->bitmap2.bits = NULL; } } /* * Read glyph directory (really a whole pass over the file). */ for (;;) { int bytes_left, flag_low_bits; unsigned int cc; PK_skip_specials(fontp); if (PK_flag_byte == PK_POST) break; flag_low_bits = PK_flag_byte & 0x7; if (flag_low_bits == 7) { bytes_left = four(fontp->file); cc = four(fontp->file); } else if (flag_low_bits > 3) { bytes_left = ((flag_low_bits - 4) << 16) + two(fontp->file); cc = one(fontp->file); } else { bytes_left = (flag_low_bits << 8) + one(fontp->file); cc = one(fontp->file); } fontp->glyph[cc].addr = ftell(fontp->file); fontp->glyph[cc].x2 = PK_flag_byte; Fseek(fontp->file, (long) bytes_left, 1); } } static void read_char(fontp, ch) register struct font *fontp; ubyte ch; { int i, j; ubyte n; int row_bit_pos; Boolean paint_switch; BMUNIT *cp; register struct glyph *g; register FILE *fp = fontp->file; long fpwidth; BMUNIT word; int word_weight, bytes_wide; int rows_left, h_bit, count; g = &fontp->glyph[ch]; PK_flag_byte = g->x2; PK_dyn_f = PK_flag_byte >> 4; paint_switch = ((PK_flag_byte & 8) != 0); PK_flag_byte &= 0x7; if (PK_flag_byte == 7) n = 4; else if (PK_flag_byte > 3) n = 2; else n = 1; if(debug & DBG_PK) Printf("loading pk char %d, char type %d ", ch, n); /* now read rest of character preamble */ if (n != 4) fpwidth = snum(fp, 3); else { fpwidth = sfour(fp); (void) four(fp); /* horizontal escapement */ } (void) num(fp, n); /* vertical escapement */ { unsigned long w, h; w = num(fp, n); h = num(fp, n); if (w > 0x7fff || h > 0x7fff) oops("Too large character (%d) in file %s", ch, fontp->fontname); g->bitmap.w = w; g->bitmap.h = h; } g->x = snum(fp, n); g->y = snum(fp, n); g->dvi_adv = ((double) fontp->scale * fpwidth) / (1 << 20); if (debug & DBG_PK) { if (g->bitmap.w != 0) Printf(", size=%dx%d, dvi_adv=%d", g->bitmap.w, g->bitmap.h, g->dvi_adv); putchar('\n'); } alloc_bitmap(&g->bitmap, fontp->fontname, ch); cp = (BMUNIT *) g->bitmap.bits; /* * read character data into *cp */ bytes_wide = ROUNDUP(g->bitmap.w, BITS_PER_BMUNIT) * BYTES_PER_BMUNIT; PK_bitpos = -1; if( PK_dyn_f == 14 ) /* get raster by bits */ { bzero(g->bitmap.bits, g->bitmap.h * bytes_wide); for (i = 0; i < g->bitmap.h; i++) /* get all rows */ { cp = ADD(g->bitmap.bits, i * bytes_wide); #ifndef MSBITFIRST row_bit_pos = -1; #else row_bit_pos = BITS_PER_BMUNIT; #endif for (j = 0; j < g->bitmap.w; j++) /* get one row */ { if (--PK_bitpos < 0) { word = one(fp); PK_bitpos = 7; } #ifndef MSBITFIRST if (++row_bit_pos >= BITS_PER_BMUNIT) #else if (--row_bit_pos < 0) #endif { cp++; #ifndef MSBITFIRST row_bit_pos = 0; #else row_bit_pos = BITS_PER_BMUNIT - 1; #endif } if (word & (1 << PK_bitpos)) *cp |= 1 << row_bit_pos; } } } else { /* get packed raster */ rows_left = g->bitmap.h; h_bit = g->bitmap.w; PK_repeat_count = 0; word_weight = BITS_PER_BMUNIT; word = 0; while (rows_left > 0) { count = PK_packed_num( fp ); while (count > 0) { if (count < word_weight && count < h_bit) { #ifndef MSBITFIRST if (paint_switch) word |= bit_masks[count] << (BITS_PER_BMUNIT - word_weight); #endif h_bit -= count; word_weight -= count; #ifdef MSBITFIRST if (paint_switch) word |= bit_masks[count] << word_weight; #endif count = 0; } else if (count >= h_bit && h_bit <= word_weight) { if (paint_switch) word |= bit_masks[h_bit] << #ifndef MSBITFIRST (BITS_PER_BMUNIT - word_weight); #else (word_weight - h_bit); #endif *cp++ = word; /* "output" row(s) */ for (i = PK_repeat_count * bytes_wide / BYTES_PER_BMUNIT; i > 0; --i) { *cp = *SUB(cp, bytes_wide); ++cp; } rows_left -= PK_repeat_count + 1; PK_repeat_count = 0; word = 0; word_weight = BITS_PER_BMUNIT; count -= h_bit; h_bit = g->bitmap.w; } else { if (paint_switch) #ifndef MSBITFIRST word |= bit_masks[word_weight] << (BITS_PER_BMUNIT - word_weight); #else word |= bit_masks[word_weight]; #endif *cp++ = word; word = 0; count -= word_weight; h_bit -= word_weight; word_weight = BITS_PER_BMUNIT; } } paint_switch = 1 - paint_switch; } if (cp != ((BMUNIT *) (g->bitmap.bits + bytes_wide * g->bitmap.h))) oops("Wrong number of bits stored: char. %d, font %s", ch, fontp->fontname); if (rows_left != 0 || h_bit != g->bitmap.w) oops("Bad pk file (%s), too many bits", fontp->fontname); } }