⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parseafm.c

📁 source code: Covert TXT to PDF
💻 C
📖 第 1 页 / 共 3 页
字号:
/*--------------------------------------------------------------------------  ----- File:        parseAFM.c  ----- Author:      Adobe Systems Inc., modifications by                     Rainer Menzner (Rainer.Menzner@web.de)  ----- Date:        2001-04-01  ----- Description: This file is part of the t1-library. It is the original                     parseAFM.h modified at a few points, especially for		     reading MSDOS-style AFM files..  ----- Copyright:   t1lib is copyrighted (c) Rainer Menzner, 1996-2001.                     As of version 0.5, t1lib is distributed under the		     GNU General Public Library Lincense. The		     conditions can be found in the files LICENSE and		     LGPL, which should reside in the toplevel		     directory of the distribution.  Please note that 		     there are parts of t1lib that are subject to		     other licenses:		     The parseAFM-package is copyrighted by Adobe Systems		     Inc.		     The type1 rasterizer is copyrighted by IBM and the		     X11-consortium.  ----- Warranties:  Of course, there's NO WARRANTY OF ANY KIND :-)  ----- Credits:     I want to thank IBM and the X11-consortium for making                     their rasterizer freely available.		     Also thanks to Piet Tutelaers for his ps2pk, from		     which I took the rasterizer sources in a format		     independent from X11.                     Thanks to all people who make free software living!--------------------------------------------------------------------------*//* * (C) 1988, 1989, 1990 by Adobe Systems Incorporated. All rights reserved. * * This file may be freely copied and redistributed as long as: *   1) This entire notice continues to be included in the file,  *   2) If the file has been modified in any way, a notice of such *      modification is conspicuously indicated. * * PostScript, Display PostScript, and Adobe are registered trademarks of * Adobe Systems Incorporated. *  * ************************************************************************ * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR  * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY  * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION,  * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY,  * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. * ************************************************************************ *//* parseAFM.c *  * This file is used in conjuction with the parseAFM.h header file. * This file contains several procedures that are used to parse AFM * files. It is intended to work with an application program that needs * font metric information. The program can be used as is by making a * procedure call to "parseFile" (passing in the expected parameters) * and having it fill in a data structure with the data from the  * AFM file, or an application developer may wish to customize this * code. * * There is also a file, parseAFMclient.c, that is a sample application * showing how to call the "parseFile" procedure and how to use the data * after "parseFile" has returned. * * Please read the comments in parseAFM.h and parseAFMclient.c. * * History: *	original: DSM  Thu Oct 20 17:39:59 PDT 1988 *  modified: DSM  Mon Jul  3 14:17:50 PDT 1989 *    - added 'storageProblem' return code *	  - fixed bug of not allocating extra byte for string duplication *    - fixed typos *  modified: DSM  Tue Apr  3 11:18:34 PDT 1990 *    - added free(ident) at end of parseFile routine *  modified: DSM  Tue Jun 19 10:16:29 PDT 1990 *    - changed (width == 250) to (width = 250) in initializeArray */#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <sys/types.h>  /* this seems to be necessary on some SCO-systems */#if !defined(_MSC_VER)#  include <sys/file.h>#endif#include <math.h>#include <string.h>#include "parseAFM.h" #define lineterm EOL	/* line terminating character */#define normalEOF 1	/* return code from parsing routines used only */			/* in this module */#define Space "space"   /* used in string comparison to look for the width */			/* of the space character to init the widths array */#define False "false"   /* used in string comparison to check the value of */			/* boolean keys (e.g. IsFixedPitch)  */#define MATCH(A,B)		(strncmp((A),(B), MAX_NAME) == 0)/* Note: The functions token and linetoken are  extended to be able   to parse AFM files with DOS-style line-ends under UNIX. I don't know   why AFM files which according to Adobe are explicitly intended to   be used under UNIX have MSDOS-style line ends.   However, we parse the tokens based on the following atoms. This should   work on any system.*/#define CR       '\r'    /* a carriage return */#define LF       '\n'    /* a linefeed, which is a newline under UNIX */#define CTRL_Z   0x1A    /* some AFM files have this characters as an end			    of file indicator. Who know why :) ? *//*************************** GLOBALS ***********************/static char *ident = NULL; /* storage buffer for keywords *//* "shorts" for fast case statement  * The values of each of these enumerated items correspond to an entry in the * table of strings defined below. Therefore, if you add a new string as  * new keyword into the keyStrings table, you must also add a corresponding * parseKey AND it MUST be in the same position! * * IMPORTANT: since the sorting algorithm is a binary search, the strings of * keywords must be placed in lexicographical order, below. [Therefore, the  * enumerated items are not necessarily in lexicographical order, depending  * on the name chosen. BUT, they must be placed in the same position as the  * corresponding key string.] The NOPE shall remain in the last position,  * since it does not correspond to any key string, and it is used in the  * "recognize" procedure to calculate how many possible keys there are. */typedef enum {  ASCENDER, CHARBBOX, CODE, COMPCHAR, CAPHEIGHT, 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, TRACKKERN, UNDERLINEPOSITION,   UNDERLINETHICKNESS, VERSION, XYWIDTH, XWIDTH, WEIGHT, XHEIGHT,  NOPE} PARSEKEY;/* keywords for the system:   * This a table of all of the current strings that are vaild AFM keys. * Each entry can be referenced by the appropriate parseKey value (an * enumerated data type defined above). If you add a new keyword here,  * a corresponding parseKey MUST be added to the enumerated data type * defined above, AND it MUST be added in the same position as the  * string is in this table. * * IMPORTANT: since the sorting algorithm is a binary search, the keywords * must be placed in lexicographical order. And, NULL should remain at the * end. */static char *keyStrings[] = {  "Ascender", "B", "C", "CC", "CapHeight", "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", "TrackKern", "UnderlinePosition",   "UnderlineThickness", "Version", "W", "WX", "Weight", "XHeight",  NULL };  /*************************** PARSING ROUTINES **************/   /*************************** token *************************//*  A "AFM File Conventions" tokenizer. That means that it will *  return the next token delimited by white space.  See also *  the `linetoken' routine, which does a similar thing but  *  reads all tokens until the next end-of-line. */static char *token(stream)   FILE *stream;{    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 */} /* token *//*************************** linetoken *************************//*  "linetoken" will get read all tokens until the EOL character from *  the given stream.  This is used to get any arguments that can be *  more than one word (like Comment lines and FullName). */static char *linetoken(stream)  FILE *stream;{    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 */} /* linetoken *//*************************** recognize *************************//*  This function tries to match a string to a known list of *  valid AFM entries (check the keyStrings array above).  *  "ident" contains everything from white space through the *  next space, tab, or ":" character. * *  The algorithm is a standard Knuth binary search. */static PARSEKEY recognize(ident)  register char *ident;{    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;    } /* recognize *//************************* parseGlobals *****************************//*  This function is called by "parseFile". It will parse the AFM File *  up to the "StartCharMetrics" keyword, which essentially marks the *  end of the Global Font Information and the beginning of the character *  metrics information.  * *  If the caller of "parseFile" specified that it wanted the Global *  Font Information (as defined by the "AFM File Specification" *  document), then that information will be stored in the returned  *  data structure. * *  Any Global Font Information entries that are not found in a  *  given file, will have the usual default initialization value *  for its type (i.e. entries of type int will be 0, etc). * *  This function returns an error code specifying whether there was  *  a premature EOF or a parsing error. This return value is used by  *  parseFile to determine if there is more file to parse. */ static BOOL parseGlobals(fp, gfi)  FILE *fp;  register GlobalFontInfo *gfi;{      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:                    keyword = linetoken(fp);                    break;                case FONTNAME:                    keyword = token(fp);                    gfi->fontName = (char *) malloc(strlen(keyword) + 1);                    strcpy(gfi->fontName, keyword);                    break;                case ENCODINGSCHEME:                    keyword = token(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 = token(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 = token(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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -