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 a

⟦8928a99ef⟧ TextFile

    Length: 8412 (0x20dc)
    Types: TextFile
    Names: »afm.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/pfd2tfm/src/afm.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.  */


/*
 * This file contains all the stuff, which has to do with reading
 * in an AFM file.
 */

#include <stdio.h>
#include "defs.h"
#include "pfd2tfm.h"
#include "char.h"
#include "pdr.h"

extern int Verbose;
extern char * StrcpyAlloc();
extern void MapCharInit();
extern void ExcludeCharInit();
extern char * SetUpHashTable();

/* Hash table, which maps character names to character codes */
char * CharacterNameHashTable;
extern char * LookUpKeyInHashTable();
extern char * InsertKeyIntoHashTable();

extern char * MapHashTable;
extern char * ExcludeCharHashTable;

void CheckCharCode();

/* One entry for each character read in. Character code used
 * as index. */
CAFM AfmChar[MAX_CHAR_PS];
char * AfmCharacterName; /* name of character currently being read in */

/* Code of the character currently being read in.
 * Special code EXCLUDED_CHAR_CODE for an excluded character. */
int  CharCode; 

/* Use the kerning and ligature information from the AFM file in the
 * first place ? */
int  UseAfmKernings;
int  UseAfmLigatures;

/* Table with all the kerning corrections in the AFM or PFD file */
KPX KerningTable [KERNS];
/* Index into above table, points to next free entry */
int KerningTableIndex;

/* Ligature information is stored here */
struct lig LigatureTable [LIGATURES];
int LigatureTableIndex;

/* Whether font is fixed pitch or not */
int IsFixedPitch;
/* XHeight read from AFM file */
int XHeight;

/*
 * AfmCharDo
 * *********
 * This function is called each time a character has been
 * read in from the AFM file, excluding the ligature information
 * following a character specification.
 * code: the character code as found in the AFM file
 * name: the character name
 * wx: the x width of the character
 * llx, lly, urx, ury: bounding box, ll: lower left, ur: upper right
 */
void
AfmCharDo (code, name, wx, llx, lly, urx, ury)
     int code;
     char * name;
     int wx;
     int llx, lly, urx, ury;
{
  CHNP p; /* Returned from character name hash table */
  int ret;

  /* Try to find a character code for this character; just
   * forget about the character if you didn't find one. */
  ret = comind(code, name);

  /* The first part of this Verbose statement is in comind() */
  if (Verbose > V_SOME) {
    if (ret)
      fprintf (stderr, "'%3o (TeX), width = %4d", CharCode, wx);
    else
      fprintf (stderr, "<none>\n");
  }
  if (!ret)
    return;

  /* Check the legality of the index */
  CheckCharCode(CharCode, "AfmCharDo()");

  AfmChar[CharCode].c_used = TRUE;
  AfmChar[CharCode].c_string = name;
  AfmChar[CharCode].c_wx = wx;
  AfmChar[CharCode].c_llx = llx;
  AfmChar[CharCode].c_lly = lly;
  AfmChar[CharCode].c_urx = urx;
  AfmChar[CharCode].c_ury = ury;

  /* Insert the character into the character name hash table */
  p = (CHNP) InsertKeyIntoHashTable (CharacterNameHashTable, name);
  p->c_code = CharCode;

  /* Done */
  if (Verbose > V_SOME)
    fprintf (stderr, "\n");

#ifdef DEBUG
  fflush(stderr);
#endif
}

/*
 * AfmInit
 * *******
 * Initialisation procedure for the AfmChar array.
 * Initializes a bunch of other stuff too, like the hash table
 * for characters and ligatures.
 */
void
AfmInit()
{
  int i;

  CharCode = 0;
  XHeight = 0;

  for (i=0; i<MAX_CHAR_PS; i++) {
    AfmChar[i].c_used = FALSE;
    AfmChar[i].c_type = CT_NONE;
    AfmChar[i].c_execps_type = 0;
    AfmChar[i].c_map = FALSE;
    AfmChar[i].c_string = NULL;
    AfmChar[i].c_kern = NULL;
    AfmChar[i].c_lig = NULL;
    AfmChar[i].c_tfm = 0;
  }
  MapCharInit();
  ExcludeCharInit();
  CharacterNameHashTable =
    SetUpHashTable (255, sizeof(CHN), "CharacterNames->CharacterCodes");
  UseAfmKernings = TRUE;
  UseAfmLigatures= TRUE;
}

/*
 * CharNameToIndex
 * ***************
 * Return the character index of a character, of which a name
 * is give. Generate fatal error if not found.
 *
 * name: the name of the character.
 * RET: character index of the character
 */
int 
CharNameToIndex(name)
     char * name;
{
  CHNP p;

  p = (CHNP) LookUpKeyInHashTableE (CharacterNameHashTable, name,
				    "CharNameToIndex()");
  return (p->c_code);
}

/*
 * CharNameToIndexNoError
 * **********************
 * Return the character index of a character, of which a name
 * is give. Return -1 if the characters is not in the hash table.
 *
 * name: the name of the character.
 * RET: character index of the character
 */
int 
CharNameToIndexNoError(name)
     char * name;
{
  CHNP p;

  p = (CHNP) LookUpKeyInHashTable (CharacterNameHashTable, name,
				   "CharNameToIndex()");
  if (p == NULL)
    return (-1);
  return (p->c_code);
}

/*
 * CheckCharCode
 * *************
 * Check whether a character code is legal or not.
 *
 * code:    which character code
 * message: error message, which should point to where
 *          the error occured.
 */
void
CheckCharCode (code, message)
     int code;
     char * message;
{
  if (code >= 0 && code < MAX_CHAR_PS)
    return;
  Fatal2 ("Character code out of range (%s)", message);
}

/*
 * comind
 * ******
 * Compute character index. This procedure is called from
 * inside of AfmCharDo.
 * code: as found in the AFM file.
 * name: the character's name.
 * RET: TRUE if you found a character code which is returned
 *            in CharCode; otherwise return FALSE.
 * SIDEFFECT: sets CharCode to the proper value. "code" irrelevant
 *            afterwards.
 */
int
comind (code, name)
     int code;
     char * name;
{
  CRMP p2; /* Mapped code */
  int code2; /* Second code, from LookUp in default table */

  CharCode = -1;

  /* Save character's name. */
  AfmCharacterName = name;

  /* Print the character's name. */
  if (Verbose > V_SOME) {
    if (code == NO_CODE_IN_AFM)
      fprintf (stderr, "  -1 (afm), \"%-15s\", ",       name);
    else
      fprintf (stderr, "'%3o (afm), \"%-15s\", ", code, name);
  }

  /*
   * Compute the character's code. NO_CODE_IN_AFM means that the
   * the AFM file does not contain a "recommended" character code
   * (the character code in the AFM file is -1).
   *
   * The result of the following computation is to set the variable
   * "CharCode" to the character code to be used for the rest of
   * the execution of this program. "code" which was loaded from
   * the AFM file, is no more relevant afterwards.
   */

  /* (1) Is the character excluded? If so, just forget it! */
  if (LookUpKeyInHashTable(ExcludeCharHashTable, name) != NULL) {
#ifdef DEBUG
    fprintf (stderr, "<excluded>");
#endif
    return (FALSE);
  }

  p2 = NULL;

  /* (2) Has the character been mapped? This is the MapChar instruction
   *     of the PFD file. */
  if ((p2 = (CRMP)LookUpKeyInHashTable(MapHashTable, name)) != NULL) {
    /* yes */
    CharCode = p2->r_code;
    if (AfmChar[CharCode].c_used)
      Fatal2 ("AfmCharDo(): Character code '%o already used (map)", CharCode);
    AfmChar[CharCode].c_type = CT_ASS;
    return(TRUE);
  }

  /* No map.
   * (3) The default character code vector may assign a new code.
   */
  if ((code2 = LookUpDefCode(name)) != -1) {
    CharCode = code2;
    AfmChar[CharCode].c_type = CT_ASS;
    return (TRUE);
  }

  /* (4) Now let's see what the AFM file says. If no character
   * code is recommended drop this character. */
  if (code == -1) {
    fprintf (stderr, "AfmCharDo(): No default for \"%s\"\n", name);
    return (FALSE);
  }

  CharCode = code;
  if (! AfmChar[CharCode].c_used) {
    CharCode = code;
    AfmChar[CharCode].c_type = CT_AFM;
    return (TRUE);
  }
  return (FALSE);
}