Back to index

tetex-bin  3.0
Defines | Enumerations | Functions | Variables
parseAFM.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/file.h>
#include <math.h>
#include <string.h>
#include "parseAFM.h"
#include "t1base.h"
#include "t1misc.h"

Go to the source code of this file.

Defines

#define lineterm   EOL /* line terminating character */
#define normalEOF   1 /* return code from parsing routines used only */
#define Space   "space" /* used in string comparison to look for the width */
#define False   "false" /* used in string comparison to check the value of */
#define MATCH(A, B)   (strncmp((A),(B), MAX_NAME) == 0)
#define CR   '\r' /* a carriage return */
#define LF   '\n' /* a linefeed, which is a newline under UNIX */
#define CTRL_Z

Enumerations

enum  PARSEKEY {
  ASCENDER, CHARBBOX, CODE, COMPCHAR,
  CAPHEIGHT, CHARACTERSET, COMMENT, DESCENDER,
  ENCODINGSCHEME, ENDCHARMETRICS, ENDCOMPOSITES, ENDFONTMETRICS,
  ENDKERNDATA, ENDKERNPAIRS, ENDTRACKKERN, FAMILYNAME,
  FONTBBOX, FONTNAME, FULLNAME, ISFIXEDPITCH,
  ITALICANGLE, KERNPAIR, KERNPAIRXAMT, LIGATURE,
  CHARNAME, NOTICE, COMPCHARPIECE, STARTCHARMETRICS,
  STARTCOMPOSITES, STARTFONTMETRICS, STARTKERNDATA, STARTKERNPAIRS,
  STARTTRACKKERN, STDHW, STDVW, TRACKKERN,
  UNDERLINEPOSITION, UNDERLINETHICKNESS, VERSION, XYWIDTH,
  XWIDTH, WEIGHT, XHEIGHT, NOPE
}

Functions

static char * token (FILE *stream)
static char * linetoken (FILE *stream)
static PARSEKEY recognize (char *ident)
static BOOL parseGlobals (FILE *fp, GlobalFontInfo *gfi)
static int parseCharWidths (FILE *fp, int *cwi)
static int parseCharMetrics (FILE *fp, FontInfo *fi)
static int parseTrackKernData (FILE *fp, FontInfo *fi)
static int parsePairKernData (FILE *fp, FontInfo *fi)
static int parseCompCharData (FILE *fp, FontInfo *fi)
int T1lib_parseFile (FILE *fp, FontInfo **fi, FLAGS flags)

Variables

static char * ident = NULL
static char * keyStrings []

Define Documentation

#define CR   '\r' /* a carriage return */

Definition at line 115 of file parseAFM.c.

#define CTRL_Z
Value:
0x1A    /* some AFM files have this characters as an end
                         of file indicator. Who know why :) ? */

Definition at line 117 of file parseAFM.c.

#define False   "false" /* used in string comparison to check the value of */

Definition at line 100 of file parseAFM.c.

#define LF   '\n' /* a linefeed, which is a newline under UNIX */

Definition at line 116 of file parseAFM.c.

#define lineterm   EOL /* line terminating character */

Definition at line 95 of file parseAFM.c.

#define MATCH (   A,
  B 
)    (strncmp((A),(B), MAX_NAME) == 0)

Definition at line 103 of file parseAFM.c.

#define normalEOF   1 /* return code from parsing routines used only */

Definition at line 96 of file parseAFM.c.

#define Space   "space" /* used in string comparison to look for the width */

Definition at line 98 of file parseAFM.c.


Enumeration Type Documentation

enum PARSEKEY
Enumerator:
ASCENDER 
CHARBBOX 
CODE 
COMPCHAR 
CAPHEIGHT 
CHARACTERSET 
COMMENT 
DESCENDER 
ENCODINGSCHEME 
ENDCHARMETRICS 
ENDCOMPOSITES 
ENDFONTMETRICS 
ENDKERNDATA 
ENDKERNPAIRS 
ENDTRACKKERN 
FAMILYNAME 
FONTBBOX 
FONTNAME 
FULLNAME 
ISFIXEDPITCH 
ITALICANGLE 
KERNPAIR 
KERNPAIRXAMT 
LIGATURE 
CHARNAME 
NOTICE 
COMPCHARPIECE 
STARTCHARMETRICS 
STARTCOMPOSITES 
STARTFONTMETRICS 
STARTKERNDATA 
STARTKERNPAIRS 
STARTTRACKKERN 
STDHW 
STDVW 
TRACKKERN 
UNDERLINEPOSITION 
UNDERLINETHICKNESS 
VERSION 
XYWIDTH 
XWIDTH 
WEIGHT 
XHEIGHT 
NOPE 

Definition at line 140 of file parseAFM.c.


Function Documentation

static char* linetoken ( FILE stream) [static]

Definition at line 229 of file parseAFM.c.

{
    int ch, idx;

    while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); 
    
    idx = 0;
    while (ch != EOF && ch != CR  && ch != LF && ch != CTRL_Z) 
    {
        ident[idx++] = ch;
        ch = fgetc(stream);
    } /* while */
    
    ungetc(ch, stream);
    ident[idx] = 0;

    return(ident);   /* returns pointer to the token */

Here is the caller graph for this function:

static int parseCharMetrics ( FILE fp,
FontInfo fi 
) [static]

Definition at line 664 of file parseAFM.c.

{  
    BOOL cont = T1LIB_TRUE, firstTime = T1LIB_TRUE;
    int error = ok, count = 0;
    register CharMetricInfo *temp = fi->cmi;
    register char *keyword;
  
    while (cont)
    {
        keyword = token(fp);
        if (keyword == NULL)
        {
            error = earlyEOF;
            break; /* get out of loop */
        }
        switch(recognize(keyword))
        {
            case COMMENT:
                keyword = linetoken(fp);
                break; 
            case CODE:
                if (count < fi->numOfChars)
                { 
                    if (firstTime) firstTime = T1LIB_FALSE;
                    else temp++;
                    temp->code = atoi(token(fp));
                    count++;
                }
                else
                {
                    error = parseError;
                    cont = T1LIB_FALSE;
                }
                break;
            case XYWIDTH:
                temp->wx = atoi(token(fp));
                temp->wy = atoi(token(fp));
                break;                 
            case XWIDTH: 
                temp->wx = atoi(token(fp));
                break;
            case CHARNAME: 
                keyword = token(fp);
                temp->name = (char *) malloc(strlen(keyword) + 1);
                strcpy(temp->name, keyword);
                break;            
            case CHARBBOX: 
                temp->charBBox.llx = atoi(token(fp));
                temp->charBBox.lly = atoi(token(fp));
                temp->charBBox.urx = atoi(token(fp));
                temp->charBBox.ury = atoi(token(fp));
                break;
            case LIGATURE: {
                Ligature **tail = &(temp->ligs);
                Ligature *node = *tail;
                
                if (*tail != NULL)
                {
                    while (node->next != NULL)
                        node = node->next;
                    tail = &(node->next); 
                }
                
                *tail = (Ligature *) calloc(1, sizeof(Ligature));
                keyword = token(fp);
                (*tail)->succ = (char *) malloc(strlen(keyword) + 1);
                strcpy((*tail)->succ, keyword);
                keyword = token(fp);
                (*tail)->lig = (char *) malloc(strlen(keyword) + 1);
                strcpy((*tail)->lig, keyword);
                break; }
            case ENDCHARMETRICS:
                cont = T1LIB_FALSE;;
                break; 
            case ENDFONTMETRICS: 
                cont = T1LIB_FALSE;
                error = normalEOF;
                break; 
            case NOPE:
            default:
                error = parseError; 
                break; 
        } /* switch */
    } /* while */
    
    if ((error == ok) && (count != fi->numOfChars))
        error = parseError;
    
    return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static int parseCharWidths ( FILE fp,
int cwi 
) [static]

Definition at line 563 of file parseAFM.c.

{  
    BOOL cont = T1LIB_TRUE, save = (cwi != NULL);
    int pos = 0, error = ok;
    register char *keyword;
    
    while (cont)
    {
        keyword = token(fp);
          /* Have reached an early and unexpected EOF. */
          /* Set flag and stop parsing */
        if (keyword == NULL)
        {
            error = earlyEOF;
            break; /* get out of loop */
        }
        if (!save)   
          /* get tokens until the end of the Char Metrics section without */
          /* saving any of the data*/
            switch (recognize(keyword))  
            {                      
                case ENDCHARMETRICS:
                    cont = T1LIB_FALSE;
                    break; 
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                default: 
                    break;
            } /* switch */
        else
          /* otherwise parse entire char metrics section, saving */
          /* only the char x-width info */
            switch(recognize(keyword))
            {
                case COMMENT:
                    keyword = linetoken(fp);
                    break;
                case CODE:
                    keyword = token(fp);
                    pos = atoi(keyword);
                    break;
                case XYWIDTH:
                /* PROBLEM: Should be no Y-WIDTH when doing "quick & dirty" */
                    keyword = token(fp); keyword = token(fp); /* eat values */
                    error = parseError;
                    break;
                case XWIDTH:
                    keyword = token(fp);
                    if (pos >= 0) /* ignore unmapped chars */
                        cwi[pos] = atoi(keyword);
                    break;
                case ENDCHARMETRICS:
                    cont = T1LIB_FALSE;
                    break; 
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                case CHARNAME:     /* eat values (so doesn't cause parseError) */
                    keyword = token(fp); 
                    break;
              case CHARBBOX: 
                    keyword = token(fp); keyword = token(fp);
                    keyword = token(fp); keyword = token(fp);
                  break;
              case LIGATURE:
                    keyword = token(fp); keyword = token(fp);
                  break;
                case NOPE:
                default: 
                    error = parseError;
                    break;
            } /* switch */
    } /* while */
    
    return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static int parseCompCharData ( FILE fp,
FontInfo fi 
) [static]

Definition at line 1005 of file parseAFM.c.

{  
    BOOL cont = T1LIB_TRUE, firstTime = T1LIB_TRUE, save = (fi->ccd != NULL);
    int pos = 0, j = 0, error = ok, ccount = 0, pcount = 0;
    register char *keyword;
  
    while (cont)
    {
        keyword = token(fp);
        if (keyword == NULL)
          /* Have reached an early and unexpected EOF. */
          /* Set flag and stop parsing */
        {
            error = earlyEOF;
            break; /* get out of loop */
        }
        if (ccount > fi->numOfComps)
        {
            error = parseError;
            break; /* get out of loop */
        }
        if (!save)
          /* get tokens until the end of the Composite Character info */
          /* section without saving any of the data */
            switch(recognize(keyword))
            {
                case ENDCOMPOSITES:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                default:
                    break;
            } /* switch */
       else
          /* otherwise parse entire Composite Character info section, */
          /* saving the data */
            switch(recognize(keyword))
            {
                case COMMENT:
                    keyword = linetoken(fp);
                    break;
                case COMPCHAR:
                    if (ccount < fi->numOfComps)
                    {
                        keyword = token(fp);
                        if (pcount != fi->ccd[pos].numOfPieces)
                            error = parseError;
                        pcount = 0;
                        if (firstTime) firstTime = T1LIB_FALSE;
                        else pos++;
                        fi->ccd[pos].ccName = (char *) 
                            malloc(strlen(keyword) + 1);
                        strcpy(fi->ccd[pos].ccName, keyword);
                        keyword = token(fp);
                        fi->ccd[pos].numOfPieces = atoi(keyword);
                        fi->ccd[pos].pieces = (Pcc *)
                            calloc(fi->ccd[pos].numOfPieces, sizeof(Pcc));
                        j = 0;
                        ccount++;
                    }
                    else
                    {
                        error = parseError;
                        cont = T1LIB_FALSE;
                    }
                    break;
                case COMPCHARPIECE:
                    if (pcount < fi->ccd[pos].numOfPieces)
                    {
                        keyword = token(fp);
                        fi->ccd[pos].pieces[j].pccName = (char *) 
                                malloc(strlen(keyword) + 1);
                        strcpy(fi->ccd[pos].pieces[j].pccName, keyword);
                        keyword = token(fp);
                        fi->ccd[pos].pieces[j].deltax = atoi(keyword);
                        keyword = token(fp);
                        fi->ccd[pos].pieces[j++].deltay = atoi(keyword);
                        pcount++;
                    }
                    else
                        error = parseError;
                    break;
                case ENDCOMPOSITES:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                case NOPE:
                default:
                    error = parseError;
                    break;
            } /* switch */
    } /* while */
    
    if (error == ok && ccount != fi->numOfComps)
        error = parseError;
    
    return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static BOOL parseGlobals ( FILE fp,
GlobalFontInfo gfi 
) [static]

Definition at line 304 of file parseAFM.c.

{  
    BOOL cont = T1LIB_TRUE, save = (gfi != NULL);
    int error = ok;
    register char *keyword;
    
    while (cont)
    {
        keyword = token(fp);
        
        if (keyword == NULL)
          /* Have reached an early and unexpected EOF. */
          /* Set flag and stop parsing */
        {
            error = earlyEOF;
            break;   /* get out of loop */
        }
        if (!save)   
          /* get tokens until the end of the Global Font info section */
          /* without saving any of the data */
            switch (recognize(keyword))  
            {                      
                case STARTCHARMETRICS:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:      
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                default:
                    break;
            } /* switch */
        else
          /* otherwise parse entire global font info section, */
          /* saving the data */
            switch(recognize(keyword))
            {
                case STARTFONTMETRICS:
                    keyword = token(fp);
                    gfi->afmVersion = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->afmVersion, keyword);
                    break;
                case COMMENT:
                /* We ignore the following keywords. They are only listed
                   here in order to prevent from "Unknown Keyword" errors. */
                case CHARACTERSET:
                case STDHW:
                case STDVW:
                    keyword = linetoken(fp);
                    break;
                case FONTNAME:
                    keyword = linetoken(fp);
                    gfi->fontName = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->fontName, keyword);
                    break;
                case ENCODINGSCHEME:
                    keyword = linetoken(fp);
                    gfi->encodingScheme = (char *) 
                     malloc(strlen(keyword) + 1);
                    strcpy(gfi->encodingScheme, keyword);
                    break; 
                case FULLNAME:
                    keyword = linetoken(fp);
                    gfi->fullName = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->fullName, keyword);
                    break; 
                case FAMILYNAME:           
                   keyword = linetoken(fp);
                    gfi->familyName = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->familyName, keyword);
                    break; 
                case WEIGHT:
                    keyword = linetoken(fp);
                    gfi->weight = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->weight, keyword);
                    break;
                case ITALICANGLE:
                    keyword = token(fp);
                    gfi->italicAngle = atof(keyword);
                    if (errno == ERANGE) error = parseError;
                    break;
                case ISFIXEDPITCH:
                    keyword = token(fp);
                    if (MATCH(keyword, False))
                        gfi->isFixedPitch = 0;
                    else 
                        gfi->isFixedPitch = 1;
                    break; 
                   case UNDERLINEPOSITION:
                    keyword = token(fp);
                   gfi->underlinePosition = atoi(keyword);
                    break; 
                case UNDERLINETHICKNESS:
                    keyword = token(fp);
                    gfi->underlineThickness = atoi(keyword);
                    break;
                case VERSION:
                    keyword = linetoken(fp);
                    gfi->version = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->version, keyword);
                    break; 
                case NOTICE:
                    keyword = linetoken(fp);
                    gfi->notice = (char *) malloc(strlen(keyword) + 1);
                    strcpy(gfi->notice, keyword);
                    break; 
                case FONTBBOX:
                    keyword = token(fp);
                    gfi->fontBBox.llx = atoi(keyword);
                    keyword = token(fp);
                    gfi->fontBBox.lly = atoi(keyword);
                    keyword = token(fp);
                    gfi->fontBBox.urx = atoi(keyword);
                    keyword = token(fp);
                    gfi->fontBBox.ury = atoi(keyword);
                    break;
                case CAPHEIGHT:
                    keyword = token(fp);
                    gfi->capHeight = atoi(keyword);
                    break;
                case XHEIGHT:
                    keyword = token(fp);
                    gfi->xHeight = atoi(keyword);
                    break;
                case DESCENDER:
                    keyword = token(fp);
                    gfi->descender = atoi(keyword);
                    break;
                case ASCENDER:
                    keyword = token(fp);
                    gfi->ascender = atoi(keyword);
                    break;
                case STARTCHARMETRICS:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                case NOPE:
                default:
                    error = parseError;
                  T1_PrintLog( "parseGlobals()", "Unknown Keyword: %s", T1LOG_WARNING, keyword);
                    break;
            } /* switch */
    } /* while */
    
    return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static int parsePairKernData ( FILE fp,
FontInfo fi 
) [static]

Definition at line 879 of file parseAFM.c.

{  
  BOOL cont = T1LIB_TRUE, save = (fi->pkd != NULL);
  int pos = 0, error = ok, pcount = 0;
  register char *keyword;
  
  while (cont)
    {
      keyword = token(fp);
      
      if (keyword == NULL)
        {
         error = earlyEOF;
         break; /* get out of loop */
        }
      if (!save)
       /* get tokens until the end of the Pair Kerning Data */
       /* section without saving any of the data */
       switch(recognize(keyword))
         {
         case ENDKERNPAIRS:
         case ENDKERNDATA:
           cont = T1LIB_FALSE;
           break;
         case ENDFONTMETRICS:
           cont = T1LIB_FALSE;
           error = normalEOF;
           break;
         default:
           break;
         } /* switch */
      else
       /* otherwise parse entire Pair Kerning Data section, */
       /* saving the data */
       switch(recognize(keyword))
         {
         case COMMENT:
           keyword = linetoken(fp);
           break;
         case KERNPAIR:
           if (pcount < fi->numOfPairs)
             {
              keyword = token(fp);
              fi->pkd[pos].name1 = (char *) 
                malloc(strlen(keyword) + 1);
              strcpy(fi->pkd[pos].name1, keyword);
              keyword = token(fp);
              fi->pkd[pos].name2 = (char *) 
                malloc(strlen(keyword) + 1);
              strcpy(fi->pkd[pos].name2, keyword);
              keyword = token(fp);
              fi->pkd[pos].xamt = atoi(keyword);
              keyword = token(fp);
              fi->pkd[pos++].yamt = atoi(keyword);
              pcount++;
             }
           else
             {
              error = parseError;
              cont = T1LIB_FALSE;
             }
           break;
         case KERNPAIRXAMT:
           if (pcount < fi->numOfPairs)
             {
              keyword = token(fp);
              fi->pkd[pos].name1 = (char *) 
                malloc(strlen(keyword) + 1);
              strcpy(fi->pkd[pos].name1, keyword);
              keyword = token(fp);
              fi->pkd[pos].name2 = (char *) 
                malloc(strlen(keyword) + 1);
              strcpy(fi->pkd[pos].name2, keyword);
              keyword = token(fp);
              fi->pkd[pos++].xamt = atoi(keyword);
              pcount++;
             }
           else
             {
              error = parseError;
              cont = T1LIB_FALSE;
             }
           break;
         case ENDKERNPAIRS:
         case ENDKERNDATA:
           cont = T1LIB_FALSE;
           break;
         case ENDFONTMETRICS:
           cont = T1LIB_FALSE;
           error = normalEOF;
           break;
         case NOPE:
         default:
           error = parseError;
           break;
         } /* switch */
    } /* while */
    
  if (error == ok && pcount != fi->numOfPairs)
    error = parseError;
        
  return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static int parseTrackKernData ( FILE fp,
FontInfo fi 
) [static]

Definition at line 775 of file parseAFM.c.

{  
    BOOL cont = T1LIB_TRUE, save = (fi->tkd != NULL);
    int pos = 0, error = ok, tcount = 0;
    register char *keyword;
  
    while (cont)
    {
        keyword = token(fp);
        
        if (keyword == NULL)
        {
            error = earlyEOF;
            break; /* get out of loop */
        }
        if (!save)
          /* get tokens until the end of the Track Kerning Data */
          /* section without saving any of the data */
            switch(recognize(keyword))
            {
                case ENDTRACKKERN:
                case ENDKERNDATA:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                default:
                    break;
            } /* switch */
       else
          /* otherwise parse entire Track Kerning Data section, */
          /* saving the data */
            switch(recognize(keyword))
            {
                case COMMENT:
                    keyword = linetoken(fp);
                    break;
                case TRACKKERN:
                    if (tcount < fi->numOfTracks)
                    {
                        keyword = token(fp);
                        fi->tkd[pos].degree = atoi(keyword);
                        keyword = token(fp);
                        fi->tkd[pos].minPtSize = atof(keyword);
                        if (errno == ERANGE) error = parseError;
                        keyword = token(fp);
                        fi->tkd[pos].minKernAmt = atof(keyword);
                        if (errno == ERANGE) error = parseError;
                        keyword = token(fp);
                        fi->tkd[pos].maxPtSize = atof(keyword);
                        if (errno == ERANGE) error = parseError;
                        keyword = token(fp);
                        fi->tkd[pos++].maxKernAmt = atof(keyword);
                        if (errno == ERANGE) error = parseError;
                        tcount++;
                    }
                    else
                    {
                        error = parseError;
                        cont = T1LIB_FALSE;
                    }
                    break;
                case ENDTRACKKERN:
                case ENDKERNDATA:
                    cont = T1LIB_FALSE;
                    break;
                case ENDFONTMETRICS:
                    cont = T1LIB_FALSE;
                    error = normalEOF;
                    break;
                case NOPE:
                default:
                    error = parseError;
                    break;
            } /* switch */
    } /* while */
    
    if (error == ok && tcount != fi->numOfTracks)
        error = parseError;
        
    return(error);
    

Here is the call graph for this function:

Here is the caller graph for this function:

static PARSEKEY recognize ( char *  ident) [static]

Definition at line 261 of file parseAFM.c.

{
    int lower = 0, upper = (int) NOPE, midpoint=NOPE, cmpvalue;
    BOOL found = T1LIB_FALSE;

    while ((upper >= lower) && !found)
    {
        midpoint = (lower + upper)/2;
        if (keyStrings[midpoint] == NULL) break;
        cmpvalue = strncmp(ident, keyStrings[midpoint], MAX_NAME);
        if (cmpvalue == 0) found = T1LIB_TRUE;
        else if (cmpvalue < 0) upper = midpoint - 1;
        else lower = midpoint + 1;
    } /* while */

    if (found) return (PARSEKEY) midpoint;
    else return NOPE;
    

Here is the call graph for this function:

Here is the caller graph for this function:

int T1lib_parseFile ( FILE fp,
FontInfo **  fi,
FLAGS  flags 
)

Definition at line 1142 of file parseAFM.c.

{
    
    int code = ok;   /* return code from each of the parsing routines */
    int error = ok;  /* used as the return code from this function */
    
    register char *keyword; /* used to store a token */  
    
                           
    /* storage data for the global variable ident */                        
    ident = (char *) calloc(MAX_NAME, sizeof(char)); 
    if (ident == NULL) {error = storageProblem; return(error);}      
  
    (*fi) = (FontInfo *) calloc(1, sizeof(FontInfo));
    if ((*fi) == NULL) {error = storageProblem; return(error);}      
  
    if (flags & P_G) 
    {
        (*fi)->gfi = (GlobalFontInfo *) calloc(1, sizeof(GlobalFontInfo));
        if ((*fi)->gfi == NULL) {error = storageProblem; return(error);}      
    }
    
    /* The AFM File begins with Global Font Information. This section */
    /* will be parsed whether or not information should be saved. */     
    code = parseGlobals(fp, (*fi)->gfi); 
    
    if (code < 0) error = code;
    
    /* The Global Font Information is followed by the Character Metrics */
    /* section. Which procedure is used to parse this section depends on */
    /* how much information should be saved. If all of the metrics info */
    /* is wanted, parseCharMetrics is called. If only the character widths */
    /* is wanted, parseCharWidths is called. parseCharWidths will also */
    /* be called in the case that no character data is to be saved, just */
    /* to parse through the section. */
  
    if ((code != normalEOF) && (code != earlyEOF))
    {
        (*fi)->numOfChars = atoi(token(fp));
           if (flags & (P_M ^ P_W))
        {
            (*fi)->cmi = (CharMetricInfo *) 
                      calloc((*fi)->numOfChars, sizeof(CharMetricInfo));
           if ((*fi)->cmi == NULL) {error = storageProblem; return(error);}
            code = parseCharMetrics(fp, *fi);             
        }
        else
        {
            if (flags & P_W)
            { 
                (*fi)->cwi = (int *) calloc(256, sizeof(int)); 
                if ((*fi)->cwi == NULL) 
                {
                     error = storageProblem; 
                     return(error);
                }
            }
            /* parse section regardless */
            code = parseCharWidths(fp, (*fi)->cwi);
        } /* else */
    } /* if */
    
    if ((error != earlyEOF) && (code < 0)) error = code;
    
    /* The remaining sections of the AFM are optional. This code will */
    /* look at the next keyword in the file to determine what section */
    /* is next, and then allocate the appropriate amount of storage */
    /* for the data (if the data is to be saved) and call the */
    /* appropriate parsing routine to parse the section. */
    
    while ((code != normalEOF) && (code != earlyEOF)) {
      keyword = token(fp);
      if (keyword == NULL)
       /* Have reached an early and unexpected EOF. */
       /* Set flag and stop parsing */
        {
         code = earlyEOF;
         break; /* get out of loop */
        }
      switch(recognize(keyword))
        {
         /* this case has been added for t1lib because otherwise comment line
            between (i.e., outside) the main sections would lead to parse
            errors. The Adobe spec does not seem to forbid comments at
            such locations (2001-05-14, RMz) */
       case COMMENT:
         keyword = linetoken(fp);
         break;
       case STARTKERNDATA:
         break;
       case ENDKERNDATA:
         break;
       case STARTTRACKKERN:
         keyword = token(fp);
         if (flags & P_T)
           {
             (*fi)->numOfTracks = atoi(keyword);
             (*fi)->tkd = (TrackKernData *) 
              calloc((*fi)->numOfTracks, sizeof(TrackKernData));
             if ((*fi)->tkd == NULL) 
              {
                error = storageProblem; 
                return(error);
              }
           } /* if */
         code = parseTrackKernData(fp, *fi);
         break;
       case STARTKERNPAIRS:
         keyword = token(fp);
         if (flags & P_P)
           {
             (*fi)->numOfPairs = atoi(keyword);
             (*fi)->pkd = (PairKernData *) 
              calloc((*fi)->numOfPairs, sizeof(PairKernData));
             if ((*fi)->pkd == NULL) 
              {
                error = storageProblem; 
                return(error);
              }
           } /* if */
         code = parsePairKernData(fp, *fi);
         break;
       case STARTCOMPOSITES:
         keyword = token(fp);
         if (flags & P_C)
           { 
             (*fi)->numOfComps = atoi(keyword);
             (*fi)->ccd = (CompCharData *) 
              calloc((*fi)->numOfComps, sizeof(CompCharData));
             if ((*fi)->ccd == NULL) 
              {
                error = storageProblem; 
                return(error);
              }
           } /* if */
         code = parseCompCharData(fp, *fi); 
         break;    
       case ENDFONTMETRICS:
         code = normalEOF;
         break;
       case NOPE:
       default:
         code = parseError;
         break;
        } /* switch */
      
      if ((error != earlyEOF) && (code < 0)) error = code;
      
    } /* while */
    
    if ((error != earlyEOF) && (code < 0)) error = code;
    
    if (ident != NULL) { free(ident); ident = NULL; }
        
    return(error);
  

Here is the call graph for this function:

Here is the caller graph for this function:

static char* token ( FILE stream) [static]

Definition at line 188 of file parseAFM.c.

{
    int ch, idx;

    /* skip over white space, instead of the systems EOL-character we check
       explicitly for CR and LF as well as for ^Z. */
    while ((ch = fgetc(stream)) == ' ' || ch == CR || ch == LF || ch == CTRL_Z || 
          ch == ',' || ch == '\t' || ch == ';');
    
    idx = 0;
    
    while (ch != EOF && ch != ' ' && ch != CR  && ch != LF &&
          ch != CTRL_Z && ch != '\t' && ch != ':' && ch != ';'){
      ident[idx++] = ch;
      ch = fgetc(stream);
    } /* while */
    
    if (ch == EOF && idx < 1) {
      return ((char *)NULL);
    }
    if (idx >= 1 && ch != ':' ) {
      ungetc(ch, stream);
    }
    if (idx < 1 ) {
      ident[idx++] = ch;    /* single-character token */
    }
    ident[idx] = 0;
    
    return(ident);   /* returns pointer to the token */


Variable Documentation

char* ident = NULL [static]

Definition at line 122 of file parseAFM.c.

char* keyStrings[] [static]
Initial value:
 {
  "Ascender", "B", "C", "CC", "CapHeight", "CharacterSet", "Comment",
  "Descender", "EncodingScheme", "EndCharMetrics", "EndComposites", 
  "EndFontMetrics", "EndKernData", "EndKernPairs", "EndTrackKern", 
  "FamilyName", "FontBBox", "FontName", "FullName", "IsFixedPitch", 
  "ItalicAngle", "KP", "KPX", "L", "N", 
  "Notice", "PCC", "StartCharMetrics", "StartComposites", 
  "StartFontMetrics", "StartKernData", "StartKernPairs", 
  "StartTrackKern", "StdHW", "StdVW", "TrackKern", "UnderlinePosition",
  "UnderlineThickness", "Version", "W", "WX", "Weight", "XHeight",
  NULL }

Definition at line 166 of file parseAFM.c.