📄 parseafm.shar
字号:
#!/bin/sh# This is a shell archive (produced by GNU sharutils 4.1.6).# To extract the files from this archive, save it to some FILE, remove# everything before the `!/bin/sh' line above, then type `sh FILE'.## Made on 1996-10-25 16:19 EDT by <rainer@mman>.# Source directory was `/usr/home/rainer/src/T1/parse_afm'.## Existing files will *not* be overwritten unless `-c' is specified.## This shar contains:# length mode name# ------ ---------- ------------------------------------------# 280 -rw-r--r-- makefile# 43280 -rw-r--r-- parseAFM.c# 11502 -rw-r--r-- parseAFM.h# 12210 -rw-r--r-- parseAFMclient.c#save_IFS=${IFS}IFS="${IFS}:"gettext_dir=FAILEDlocale_dir=FAILEDfor dir in $PATHdo if test "$gettext_dir" = "FAILED" && test -f $dir/gettext \ && ($dir/gettext --version >/dev/null 2>&1) then set `$dir/gettext --version 2>&1` if test "$3" = "GNU" then gettext_dir=$dir fi fi if test "$locale_dir" = "FAILED" && test -f $dir/shar \ && ($dir/shar --print-text-domain-dir >/dev/null 2>&1) then locale_dir=`$dir/shar --print-text-domain-dir` fidoneIFS=$save_IFSif test "$locale_dir" = "FAILED" || test "$gettext_dir" = "FAILED"then echo=echoelse TEXTDOMAINDIR=$locale_dir export TEXTDOMAINDIR TEXTDOMAIN=sharutils export TEXTDOMAIN echo="$gettext_dir/gettext --shell-script"fitouch -am 1231235999 $$.touch >/dev/null 2>&1if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touchelse shar_touch=: echo $echo 'WARNING: not restoring timestamps. Consider getting and' $echo "installing GNU \`touch', distributed in GNU File Utilities..." echofirm -f 1231235999 $$.touch#if mkdir _sh00599; then $echo 'x -' 'creating lock directory'else $echo 'failed to create lock directory' exit 1fi# ============= makefile ==============if test -f 'makefile' && test X"$1" != X"-c"; then $echo 'x -' SKIPPING 'makefile' '(file already exists)'else $echo 'x -' extracting 'makefile' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'makefile' &&XparseAFM: parseAFM.o parseAFMclient.o makefileX cc -g -o parseAFM parseAFM.o parseAFMclient.o -lm;\X shar makefile parseAFM.c parseAFM.h parseAFMclient.c > parseAFM.sharXparseAFMclient.o: parseAFMclient.cX cc -g -c parseAFMclient.cXparseAFM.o: parseAFM.cX cc -g -c parseAFM.cXSHAR_EOF $shar_touch -am 1018085596 'makefile' && chmod 0644 'makefile' || $echo 'restore of' 'makefile' 'failed' shar_count="`wc -c < 'makefile'`" test 280 -eq "$shar_count" || $echo 'makefile:' 'original size' '280,' 'current size' "$shar_count"fi# ============= parseAFM.c ==============if test -f 'parseAFM.c' && test X"$1" != X"-c"; then $echo 'x -' SKIPPING 'parseAFM.c' '(file already exists)'else $echo 'x -' extracting 'parseAFM.c' '(text)' sed 's/^X//' << 'SHAR_EOF' > 'parseAFM.c' &&/*X * (C) 1988, 1989, 1990 by Adobe Systems Incorporated. All rights reserved.X *X * This file may be freely copied and redistributed as long as:X * 1) This entire notice continues to be included in the file, X * 2) If the file has been modified in any way, a notice of suchX * modification is conspicuously indicated.X *X * PostScript, Display PostScript, and Adobe are registered trademarks ofX * Adobe Systems Incorporated.X * X * ************************************************************************X * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUTX * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMSX * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR X * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY X * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, X * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, X * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.X * ************************************************************************X */X/* parseAFM.cX * X * This file is used in conjuction with the parseAFM.h header file.X * This file contains several procedures that are used to parse AFMX * files. It is intended to work with an application program that needsX * font metric information. The program can be used as is by making aX * procedure call to "parseFile" (passing in the expected parameters)X * and having it fill in a data structure with the data from the X * AFM file, or an application developer may wish to customize thisX * code.X *X * There is also a file, parseAFMclient.c, that is a sample applicationX * showing how to call the "parseFile" procedure and how to use the dataX * after "parseFile" has returned.X *X * Please read the comments in parseAFM.h and parseAFMclient.c.X *X * History:X * original: DSM Thu Oct 20 17:39:59 PDT 1988X * modified: DSM Mon Jul 3 14:17:50 PDT 1989X * - added 'storageProblem' return codeX * - fixed bug of not allocating extra byte for string duplicationX * - fixed typosX * modified: DSM Tue Apr 3 11:18:34 PDT 1990X * - added free(ident) at end of parseFile routineX * modified: DSM Tue Jun 19 10:16:29 PDT 1990X * - changed (width == 250) to (width = 250) in initializeArrayX */X#include <stdio.h>#include <errno.h>#include <sys/file.h>#include <math.h>#include "parseAFM.h"X #define lineterm EOL /* line terminating character */#define normalEOF 1 /* return code from parsing routines used only */X /* in this module */#define Space "space" /* used in string comparison to look for the width */X /* of the space character to init the widths array */#define False "false" /* used in string comparison to check the value of */X /* boolean keys (e.g. IsFixedPitch) */X#define MATCH(A,B) (strncmp((A),(B), MAX_NAME) == 0)XXX/*************************** GLOBALS ***********************/Xstatic char *ident = NULL; /* storage buffer for keywords */XX/* "shorts" for fast case statement X * The values of each of these enumerated items correspond to an entry in theX * table of strings defined below. Therefore, if you add a new string as X * new keyword into the keyStrings table, you must also add a correspondingX * parseKey AND it MUST be in the same position!X *X * IMPORTANT: since the sorting algorithm is a binary search, the strings ofX * keywords must be placed in lexicographical order, below. [Therefore, the X * enumerated items are not necessarily in lexicographical order, depending X * on the name chosen. BUT, they must be placed in the same position as the X * corresponding key string.] The NOPE shall remain in the last position, X * since it does not correspond to any key string, and it is used in the X * "recognize" procedure to calculate how many possible keys there are.X */Xstatic enum parseKey {X ASCENDER, CHARBBOX, CODE, COMPCHAR, CAPHEIGHT, COMMENT, X DESCENDER, ENCODINGSCHEME, ENDCHARMETRICS, ENDCOMPOSITES, X ENDFONTMETRICS, ENDKERNDATA, ENDKERNPAIRS, ENDTRACKKERN, X FAMILYNAME, FONTBBOX, FONTNAME, FULLNAME, ISFIXEDPITCH, X ITALICANGLE, KERNPAIR, KERNPAIRXAMT, LIGATURE, CHARNAME, X NOTICE, COMPCHARPIECE, STARTCHARMETRICS, STARTCOMPOSITES, X STARTFONTMETRICS, STARTKERNDATA, STARTKERNPAIRS, X STARTTRACKKERN, TRACKKERN, UNDERLINEPOSITION, X UNDERLINETHICKNESS, VERSION, XYWIDTH, XWIDTH, WEIGHT, XHEIGHT,X NOPE };X/* keywords for the system: X * This a table of all of the current strings that are vaild AFM keys.X * Each entry can be referenced by the appropriate parseKey value (anX * enumerated data type defined above). If you add a new keyword here, X * a corresponding parseKey MUST be added to the enumerated data typeX * defined above, AND it MUST be added in the same position as the X * string is in this table.X *X * IMPORTANT: since the sorting algorithm is a binary search, the keywordsX * must be placed in lexicographical order. And, NULL should remain at theX * end.X */Xstatic char *keyStrings[] = {X "Ascender", "B", "C", "CC", "CapHeight", "Comment",X "Descender", "EncodingScheme", "EndCharMetrics", "EndComposites", X "EndFontMetrics", "EndKernData", "EndKernPairs", "EndTrackKern", X "FamilyName", "FontBBox", "FontName", "FullName", "IsFixedPitch", X "ItalicAngle", "KP", "KPX", "L", "N", X "Notice", "PCC", "StartCharMetrics", "StartComposites", X "StartFontMetrics", "StartKernData", "StartKernPairs", X "StartTrackKern", "TrackKern", "UnderlinePosition", X "UnderlineThickness", "Version", "W", "WX", "Weight", "XHeight",X NULL };X /*************************** PARSING ROUTINES **************/ X /*************************** token *************************/X/* A "AFM File Conventions" tokenizer. That means that it willX * return the next token delimited by white space. See alsoX * the `linetoken' routine, which does a similar thing but X * reads all tokens until the next end-of-line.X */X static char *token(stream)X FILE *stream;{X int ch, idx;XX /* skip over white space */X while ((ch = fgetc(stream)) == ' ' || ch == lineterm || X ch == ',' || ch == '\t' || ch == ';');X X idx = 0;X while (ch != EOF && ch != ' ' && ch != lineterm X && ch != '\t' && ch != ':' && ch != ';') X {X ident[idx++] = ch;X ch = fgetc(stream);X } /* while */XX if (ch == EOF && idx < 1) return ((char *)NULL);X if (idx >= 1 && ch != ':' ) ungetc(ch, stream);X if (idx < 1 ) ident[idx++] = ch; /* single-character token */X ident[idx] = 0;X X return(ident); /* returns pointer to the token */X} /* token */XX/*************************** linetoken *************************/X/* "linetoken" will get read all tokens until the EOL character fromX * the given stream. This is used to get any arguments that can beX * more than one word (like Comment lines and FullName).X */Xstatic char *linetoken(stream)X FILE *stream;{X int ch, idx;XX while ((ch = fgetc(stream)) == ' ' || ch == '\t' ); X X idx = 0;X while (ch != EOF && ch != lineterm) X {X ident[idx++] = ch;X ch = fgetc(stream);X } /* while */X X ungetc(ch, stream);X ident[idx] = 0;XX return(ident); /* returns pointer to the token */X} /* linetoken */XX/*************************** recognize *************************/X/* This function tries to match a string to a known list ofX * valid AFM entries (check the keyStrings array above). X * "ident" contains everything from white space through theX * next space, tab, or ":" character.X *X * The algorithm is a standard Knuth binary search.X */Xstatic enum parseKey recognize(ident)X register char *ident;{X int lower = 0, upper = (int) NOPE, midpoint, cmpvalue;X BOOL found = FALSE;XX while ((upper >= lower) && !found)X {X midpoint = (lower + upper)/2;X if (keyStrings[midpoint] == NULL) break;X cmpvalue = strncmp(ident, keyStrings[midpoint], MAX_NAME);X if (cmpvalue == 0) found = TRUE;X else if (cmpvalue < 0) upper = midpoint - 1;X else lower = midpoint + 1;X } /* while */XX if (found) return (enum parseKey) midpoint;X else return NOPE;X } /* recognize */XX/************************* parseGlobals *****************************/X/* This function is called by "parseFile". It will parse the AFM FileX * up to the "StartCharMetrics" keyword, which essentially marks theX * end of the Global Font Information and the beginning of the characterX * metrics information. X *X * If the caller of "parseFile" specified that it wanted the GlobalX * Font Information (as defined by the "AFM File Specification"X * document), then that information will be stored in the returned X * data structure.X *X * Any Global Font Information entries that are not found in a X * given file, will have the usual default initialization valueX * for its type (i.e. entries of type int will be 0, etc).X *X * This function returns an error code specifying whether there was X * a premature EOF or a parsing error. This return value is used by X * parseFile to determine if there is more file to parse.X */X static BOOL parseGlobals(fp, gfi)X FILE *fp;X register GlobalFontInfo *gfi;{ X BOOL cont = TRUE, save = (gfi != NULL);X int error = ok;X register char *keyword;X X while (cont)X {X keyword = token(fp);X X if (keyword == NULL)X /* Have reached an early and unexpected EOF. */X /* Set flag and stop parsing */X {X error = earlyEOF;X break; /* get out of loop */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -