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

⟦59d6aa24a⟧ TextFile

    Length: 17355 (0x43cb)
    Types: TextFile
    Names: »pdr.c«

Derivation

└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12
    └─⟦af5ba6c8e⟧ »unix3.0/DVIWARE.tar.Z« 
        └─⟦ca79c7339⟧ 
            └─⟦this⟧ »DVIware/laser-setters/dvi-to-ps/TeXPS/dvitps/src/pdr.c« 

TextFile

/* Copyright 1988 Stephan v. Bechtolsheim */

/* This file is part of the TeXPS Software Package.

The TeXPS Software Package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.  No author or distributor
accepts responsibility to anyone for the consequences of using it
or for whether it serves any particular purpose or works at all,
unless he says so in writing.  Refer to the TeXPS Software Package
General Public License for full details.

Everyone is granted permission to copy, modify and redistribute
the TeXPS Software Package, but only under the conditions described in the
TeXPS Software Package General Public License.   A copy of this license is
supposed to have been given to you along with TeXPS Software Package so you
can know your rights and responsibilities.  It should be in a
file named CopyrightLong.  Among other things, the copyright notice
and this notice must be preserved on all copies.  */


/*
 * All code which sets up PS fonts: read in pdr file, compute
 * font matrix etc.
 */

/*
 * Debug switches:
 * DEBUG_VM:       VM (virtual memory) debug
 */

#include <stdio.h>
#if SYS_V == 1
#include <string.h>
#else
#include <strings.h>
#endif
#include "defs.h"
#include "units.h"
#include "dvitps.h"
#include "extfil.h"
#include "fontd.h"
#include "pdr.h"
#include "emit.h"

/* External declarations library. */
extern char *Malloc();
extern char *StrcpyAlloc();
extern char *GetBytes();

/* Other external declarations. */
extern void HandleCheckSum();
extern void PsDownLoad();
extern int Resolution;
extern int HConvUnMag;
extern int HConv;
extern int CurFontNumber;
extern FE_P Fonts[MAX_FONTS];
extern int FontsMissing;
extern FE_P CurFontPointer;
extern int DriverMag;
extern int SmallPsVectors;
extern EX_FILES Ex_PsOutput;

int WidthVectors = TRUE; /* Download width vectors for PS fonts ? */

/*
 * ReadPdrFileInfo
 * ***************
 * Read in the information from the pdr file.
 * All the information will be read in, no later loading of any information
 * will occur. No caching therefore.
 */
void
ReadPdrFileInfo()
{
  double mfac; /* Factor to compute the Postscript matrix */
  int le; /* Length of basename */
  int i; /* Loop counter */
  PDR_P p;
  CE_P ce;
  int index; /* Index into the character array for the current font */
  double use_size_point; /* Usage size of the font in points */
  char buffer[256];
  int t;
  int check_sum; /* Check sum read from .pdr file. */
  int tfm; /* Tfm width read from .pdr file. */

  /* Open pdr file (not cached), check on correct file id, allocate
   * structure for pdr file data and insert into
   * font structure, read basename, append '\0' to it. */
  FExOpen (&(CurFontPointer->f_ex_file), EFT_READ,
	   EFQ_NO_STDIN | EFQ_CACHE | EFQ_FILE_NAME_LOADED, NULL, NULL);
  if ((t=NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2)) != PDR_FILE_ID)
    Fatal4 ("ReadPdrFileInfo(): illegal PDR_FILE_ID [%s], read: %d, expected: %d",
	    CurFontPointer->f_ex_file.ef_fn, t, PDR_FILE_ID);
  p = (PDR_P) Malloc(sizeof(PDR));
  CurFontPointer->f_pdr = p;
  p->p_same = NULL;

  p->p_basename = Malloc((le=NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1))+1);
  for (i=0; i<le; i++)
    p->p_basename[i] = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1);
  p->p_basename[le] = '\0';

  /* Checksum business. */
  check_sum = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4);
  switch (CurFontPointer->f_class) {
    case FOCLASS_AS_REQUESTED:
      HandleCheckSum (check_sum);
      break;
    case FOCLASS_REPLACEMENT_FONT:
      /* Note that when a replacement font is used the checksum as found in
	 the dvi file has no relevancy. */
      CurFontPointer->f_c = check_sum;
      break;
    default:
      Fatal ("ReadPdrFileInfo(): FOCLASS_ illegal.");
    }

  p->p_hcc = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 2); /* Highest character
								    code */
  p->p_ds = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); /* design size */
  p->p_sp = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4); /* space factor */

  /* Read in matrix elements */
  p->p_a = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4));
  p->p_b = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4));
  p->p_c = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4));
  p->p_d = FIXES_TO_FLOAT(SignExtend(EX_FP(CurFontPointer->f_ex_file), 4));

  /* Compute use size. */
  use_size_point = (double)CurFontPointer->f_s/HConvUnMag/Resolution * 72.27;

#ifdef DEBUG
  fprintf (stderr, "%% Matrix: %6.4lf %6.4lf %6.4lf %6.4lf\n",
	   p->p_a, p->p_b, p->p_c, p->p_d);
  /* Print design size and use size in pt */
  fprintf (stderr, "%% Basename: \"%s\", ", p->p_basename);
  fprintf (stderr, "Design / Use size: %6.3lf / %6.3lf [pt]\n",
	  (double) ((double)CurFontPointer->f_d/HConvUnMag)/Resolution * 72.27,
	   use_size_point);
  fprintf (stderr, "%% Font Magnification (including global): %5.3lf\n",
	   (double)(DriverMag/1000.0 * (double)CurFontPointer->f_s /
		    (double)CurFontPointer->f_d));
#endif

  /* Read in other parameters from the pdr file. */
  p->p_tx = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4);
  p->p_ty = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4);
  p->p_o = SignExtend(EX_FP(CurFontPointer->f_ex_file), 4);
  p->p_mc = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 4);
  p->p_emul = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1);
  /* Is it an invisible SliTeX font? */
  p->p_i_slitex = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1);
#ifdef DEBUG
  fprintf (stderr, "Name: %s, Invisible flag: %d\n",
	   CurFontPointer->f_n, p->p_i_slitex);
#endif

  /* If font emulation is going on, width vectors must be downloaded. */
  if (p->p_emul == 1 && !WidthVectors)
    Fatal2 ("ReadPdrFileInfo(): no -w option with font emulation (\"%s\")",
	    CurFontPointer->f_ex_file.ef_fn);
  p->p_length = NoSignExtend (EX_FP(CurFontPointer->f_ex_file), 1);
#ifdef DEBUG
  fprintf (stderr, "%% %d characters in font\n", p->p_length);
#endif

  /* Now compute the right matrix for this font. */
  mfac = DriverMag/1000.0 * 
/*	  (double)CurFontPointer->f_s / (double)CurFontPointer->f_d *   */
	    use_size_point / 72.27 * Resolution;
#ifdef DEBUG
  fprintf (stderr, "%% Matrix factor: %7.3lf\n", mfac);
#endif
  p->p_a *= mfac;
  p->p_b *= mfac;
  p->p_c *= mfac;
  p->p_d *= mfac;

  /* Initialize the character array. */
  for (i=0; i<MAX_CHAR_PS; i++) {
    CurFontPointer->f_ch[i].c_dl = FALSE;
    CurFontPointer->f_ch[i].c_type = CT_NONE;
  }

  /* Read in character names, character widths, character
     types, character names and PS procedures. This is from the character
     array in the pdr file. */
  for (i=0; i<p->p_length; i++) {
    index = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1);
#ifdef DEBUG
    fprintf (stderr, "%% ReadPdrFileInfo(): %dth char, code = '%o\n",
	     i, index);
#endif
    if (index<0 || index>=MAX_CHARS)
      Fatal2 ("ReadPdrFileInfo(): illegal character index '%o", index);
    ce = &(CurFontPointer->f_ch[index]);
    ce->c_type = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1);
    ce->c_execps_type = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 1);
#ifdef DEBUG
    fprintf (stderr, "%% ReadPdrFileInfo(): c_type: %d, c_execps_type: %d\n",
	     ce->c_type, ce->c_execps_type);
#endif

    switch (ce->c_type) {
      case CT_AFM:
      case CT_ASS:
        ce->c_dl = FALSE;
	break;
      case CT_EXECPS:
	ce->c_dl = FALSE;
	break;
      case CT_WIDTH_ONLY:
	ce->c_dl = FALSE;
	break;
      default:
	Fatal4 ("ReadPdrFileInfo(): [1] Illegal CT_ case, char: '%o, type = %d, i = %d",
		index, ce->c_type, i);
    }

    /* Load tfm with tfm width of character from .pdr file. */
    tfm = NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 4);
    switch (CurFontPointer->f_class) {
      case FOCLASS_AS_REQUESTED:
        ce->c_w_tfm = (DVIU) (CurFontPointer->f_s * FIXES_TO_FLOAT(tfm));
	break;
      case FOCLASS_REPLACEMENT_FONT:
	/* In case of a replacement font the tfm width to be used is already
	   loaded (from the font which was supposed to be used originally.)
	   Now we convert from tfm units to DVIUs. */
	ce->c_w_tfm = (DVIU) (CurFontPointer->f_s * FIXES_TO_FLOAT(ce->c_w_tfm));
	break;
      }

    /* If a width vector is used, the width of each character is rounded to
       the nearest integer position. Otherwise the width is used as directly
       read in from the pdr file. */
    if (WidthVectors)
      ce->c_rw = HConv * PixRound (ce->c_w_tfm, HConv);
    else
      ce->c_rw = ce->c_w_tfm;
    switch (ce->c_type) {
      case CT_ASS:
      case CT_AFM:
        ce->c_n = GetBytes(EX_FP(CurFontPointer->f_ex_file),
			   NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2));
	break;
      case CT_EXECPS:
	ce->c_prog = GetBytes(EX_FP(CurFontPointer->f_ex_file),
			      NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2));
	/* Here build the name to be used for the character procedure name. */
	sprintf (buffer, "@F%d==%o", CurFontNumber, index);
	ce->c_n = StrcpyAlloc(buffer);
	break;
      case CT_WIDTH_ONLY:
	if (NoSignExtend(EX_FP(CurFontPointer->f_ex_file), 2) != 0)
	  Fatal ("ReadPdrFileInfo(): CT_WIDTH_ONLY");
	ce->c_n = 0;
	break;
      default:
	Fatal ("ReadPdrFileInfo(): [2] Illegal CT_* case");
      }

#ifdef DEBUG
    fprintf (stderr, "%% PS Char '%3o, width = %6d (%s)\n",
	     index, ce->c_w_tfm, ce->c_n);
#endif
  } /* for */

  /* Note that .pdr files are not cached, because PS fonts are established
     right away. Therefore the .pdr file can be closed now. */
  FExClose (&CurFontPointer->f_ex_file);
}

/*
 * NewPSFont
 * *********
 * Establish a new PostScript font. This procedure sends all the necessary
 * information to the PostScript printer.
 */
void
NewPsFont()
{
  int vn; /* vector number for this ps font */
  int i;
  PDR_P p;
  int max_char_code; /* max character code used for PS fonts */

  if (CurFontPointer->f_new_font)
    return;
  CurFontPointer->f_new_font = TRUE;

  p = CurFontPointer->f_pdr;

  /* Some prologue files for PS fonts are needed. */
  PsDownLoad ("ps-fonts.pro", 0); /* General PS font stuff */
  PsDownLoad ("reencode.pro", 0); /* Reencode: adding character codes */
  PsDownLoad ("set-widths.pro", 0); /* Setting the width (kerning width dic) */

#ifdef DEBUG_VM
  fprintf(EX_FP(Ex_PsOutput), "(Begin PS Font) @ReportVmStatus\n");
#endif

  /* This opens the chain of PS names we give to the current
   * font as we add information and modify it. */
  CurFontPointer->f_pdr->p_ser = 0;
  fprintf (EX_FP(Ex_PsOutput), "/@F%d-0 { /%s } def\n", CurFontNumber, p->p_basename);

  /* (1) Generates a regular font */
  fprintf (EX_FP(Ex_PsOutput), "/@F%d-%d [%6.4lf %6.4lf %6.4lf %6.4lf 0.0 0.0] @F%d-%d @newfont-ps\n",
	   CurFontNumber, CurFontPointer->f_pdr->p_ser+1,
	   CurFontPointer->f_pdr->p_a,
	   CurFontPointer->f_pdr->p_b,
	   CurFontPointer->f_pdr->p_c,
	   -CurFontPointer->f_pdr->p_d,
	   CurFontNumber, CurFontPointer->f_pdr->p_ser);

  CurFontPointer->f_pdr->p_ser++;

  /* Start with the assumpation that this font needs its own width and
     character name vectors.  Vectors are identified by numbers to be able to distinguish
     among vectors of the same type but different sources. */
  vn = CurFontNumber; /* vn stands for vector number. */

  /* Check now whether another font's width and character name vector can be used. */
  for (i=0; i<MAX_FONTS; i++) {
    if (Fonts[i] != NULL &&           /* Is there such font? */
	i != CurFontNumber &&         /* Is it a different font? */
	Fonts[i]->f_type == CF_PDR && /* Is it a PostScript font? */
	Fonts[i]->f_new_font &&       /* Is it a PostScript font which has a different
					 width and character name vector from other
					 PostScript fonts? */
	ComparePdrFileLoaded (CurFontNumber, i)) { /* If yes was an answer to all the
						      preceding questions, then now check
						      whether the two fonts are comparable
						      or not. */
      /* Indeed, there is an identical font. Now generate a link which establishes that
	 the two fonts are in a certail sense equivalent. */
      if (Fonts[i]->f_pdr->p_same == NULL) {
	CurFontPointer->f_pdr->p_same = Fonts[i];
	vn = i;
      } else {
	CurFontPointer->f_pdr->p_same = Fonts[i]->f_pdr->p_same;
	vn = CurFontPointer->f_pdr->p_same->f_k;
      }
#ifdef DEBUG
      fprintf (stderr, "%% Current font %d vector-equivalent to font %d\n",
	       CurFontNumber, vn);
#endif
      break;
    }
  }

  /* Note the following DEBUG statement's messages printed which summarize
     the result from the preceding operation: vn was set initially to CurFontNumber,
     and if that has not changed, then no equivalent font was found. */
#ifdef DEBUG
  if (vn == CurFontNumber)
    fprintf (stderr, "%% Font %d, no vector-equivalent font available.\n", CurFontNumber);
  else
    fprintf (stderr, "%% Font %d: vector-equivalent font %d available.\n",
	     CurFontNumber, vn);
#endif

  /*
   * We are going to download three vectors now:
   * (a) encoding vector: a bunch of names all starting with '/'
   * (b) character codes vector:  8#0 8#1 8#20 ...
   * (c) a width vector:
   * We can save us repeating the encoding name and the encoding-codes
   * vector though if we already had such vectors from a different font.
   */

  /* Compute the maximum character code. */
  max_char_code = MAX_CHAR_PS - 1;
  if (SmallPsVectors)
    max_char_code = 127;

  if (vn == CurFontNumber) {
    /* This font is a font for which NO other equivalent font is available.
       If there is a vector-equivalent font available, do nothing.
       (a) Generate the encoding vector now. */
    fprintf (EX_FP(Ex_PsOutput), "/@Encoding-Vector-%d [\n", vn);
    for (i=0; i<=max_char_code; i++) {
      switch (CurFontPointer->f_ch[i].c_type) {
        case CT_AFM:
        case CT_ASS:
	  fprintf (EX_FP(Ex_PsOutput), "\t/%s\n", CurFontPointer->f_ch[i].c_n);
	  break;
	case CT_EXECPS:
	  break;
      }
    } /* for */
    fprintf (EX_FP(Ex_PsOutput), "] def\n");

    /* (b) Generate the character code vector next. */
    fprintf (EX_FP(Ex_PsOutput), "/@CharCode-Vector-%d [\n", vn);
    for (i=0; i<=max_char_code; i++) {
      switch (CurFontPointer->f_ch[i].c_type) {
        case CT_ASS:
        case CT_AFM:
	  fprintf (EX_FP(Ex_PsOutput), "\t8#%o\n", i);
	  break;
	case CT_EXECPS:
	  break;
      }
    } /* for */
    fprintf (EX_FP(Ex_PsOutput), "] def\n");

  } /* if vn == CurFontNumber */

  /* (c) The width vector is downloaded here. That width vector is
         never identical (that's a reasonable assumption)
	 to any other width vector. */
  if (WidthVectors) {
    fprintf (EX_FP(Ex_PsOutput), "/@Width-Vector-%d [\n", CurFontNumber);

    for (i=0; i<=max_char_code; i++) {
      switch (CurFontPointer->f_ch[i].c_type) {
        case CT_ASS:
        case CT_AFM:
	  fprintf (EX_FP(Ex_PsOutput), "\t%5.0lf\n",
	      (double)((double)CurFontPointer->f_ch[i].c_rw /
		       (double)CurFontPointer->f_s * 1000.0));
	  break;
	case CT_EXECPS:
	  break;
      }
    } /* for */
    fprintf (EX_FP(Ex_PsOutput), "] def\n");
  }

  /*
   * We modify the encoding vector, adding definitions for those characters
   * which had character code -1 in the afm file, the socalled unassigned
   * characters.
   */
  fprintf (EX_FP(Ex_PsOutput),
	   "/@F%d-%d /@F%d-%d @Encoding-Vector-%d @CharCode-Vector-%d @ReEncodeSmall\n",
	   CurFontNumber, CurFontPointer->f_pdr->p_ser,
	   CurFontNumber, CurFontPointer->f_pdr->p_ser+1, vn, vn);

  CurFontPointer->f_pdr->p_ser++;

  /* Now we add the width dictionary. */
  if (WidthVectors) {
    fprintf (EX_FP(Ex_PsOutput), "@Encoding-Vector-%d @Width-Vector-%d @MakeWidthDictionary\n",
	     vn, CurFontNumber);
    fprintf (EX_FP(Ex_PsOutput), "/@F%d-%d /@F%d-%d @AddWidthDictionary\n",
	  CurFontNumber, CurFontPointer->f_pdr->p_ser,
	  CurFontNumber, CurFontPointer->f_pdr->p_ser+1);
    CurFontPointer->f_pdr->p_ser++;
  }

#ifdef DEBUG_VM
  fprintf (EX_FP(Ex_PsOutput), "(End PS Font) @ReportVmStatus\n");
#endif
}

/*
 * ComparePdrFileLoaded
 * ********************
 * Compare two pdr files which are already loaded.
 *
 * n1, n2: the indices of two fonts.
 * RET: TRUE, if these fonts have the same basename,
 *    the same font matrix and the same encoding vector.
 */
int
ComparePdrFileLoaded (n1, n2)
     int n1;
     int n2;
{
  PDR_P p1, p2; /* Pdr file pointers. */
  int i; /* Loop counter. */
  CE c1, c2; /* Character information entries. */

  if (Fonts[n1] == NULL || Fonts[n2] == NULL)
    Fatal ("ComparePdrFileLoaded(): undefined fonts.");
  if (Fonts[n1]->f_type != CF_PDR || Fonts[n2]->f_type != CF_PDR)
    Fatal ("ComparePdrFileLoaded(): fonts are no PS fonts.");

  p1 = Fonts[n1]->f_pdr; /* Get pointers to the .pdr file. */
  p2 = Fonts[n2]->f_pdr;

  /* Different base names: the two fonts are certainly different. */
  if (Strcmp(p1->p_basename, p2->p_basename) != 0)
    return (FALSE);

  /* Compare encoding vector of the two fonts. */
  for (i=0; i<MAX_CHAR_PS; i++) {
    c1 = Fonts[n1]->f_ch[i];
    c2 = Fonts[n2]->f_ch[i];
    if (c1.c_type == CT_NONE && c2.c_type == CT_NONE)
      continue;
    if (c1.c_type != c2.c_type)
      return (FALSE);
    if (Strcmp(c1.c_n, c2.c_n) != 0) /* Compare PostScript names of the */
      return (FALSE);                /* two characters here. */
  } /* for */
  return (TRUE);
}