DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦b6cea61b2⟧ TextFile

    Length: 8330 (0x208a)
    Types: TextFile
    Names: »pk.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/crt-viewers/X/xdvi/pk.c« 

TextFile

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