|
|
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);
}
}