mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-22 02:09:28 +00:00
Initial version, thanks to <junker@jazz.snu.ac.kr> for providing this pd source from Adobe.
This commit is contained in:
parent
7fdbea0dd5
commit
39bb41d659
503
lib/xlate/parseAFM.c
Normal file
503
lib/xlate/parseAFM.c
Normal file
@ -0,0 +1,503 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* (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
|
||||
* modified: liuhai Wed Jun 11 13:53:35 PDT 1997
|
||||
* - customized for Netscape's runtime AFM file parsing
|
||||
* - only 'necessary' parsings are kept, others were thrown away
|
||||
* - PS_FontInfo is used instead of FontInfo
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mozilla modifications:
|
||||
* - Include xlate_i.h for PS_FontInfo struct definition.
|
||||
* - Minor compiler warning cleanup.
|
||||
*/
|
||||
|
||||
#include "xlate_i.h"
|
||||
#include <errno.h>
|
||||
#include <sys/file.h>
|
||||
#include <math.h>
|
||||
#include "parseAFM.h"
|
||||
/*
|
||||
#include "sunos.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)
|
||||
|
||||
|
||||
|
||||
/*************************** 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.
|
||||
*/
|
||||
|
||||
static enum parseKey {
|
||||
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 };
|
||||
|
||||
/* 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 */
|
||||
while ((ch = fgetc(stream)) == ' ' || ch == lineterm ||
|
||||
ch == ',' || ch == '\t' || ch == ';');
|
||||
|
||||
idx = 0;
|
||||
while (ch != EOF && ch != ' ' && ch != lineterm
|
||||
&& 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 != lineterm)
|
||||
{
|
||||
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 enum parseKey recognize(ident)
|
||||
register char *ident;
|
||||
{
|
||||
int lower = 0, upper = (int) NOPE, midpoint, cmpvalue;
|
||||
BOOL found = 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 = TRUE;
|
||||
else if (cmpvalue < 0) upper = midpoint - 1;
|
||||
else lower = midpoint + 1;
|
||||
} /* while */
|
||||
|
||||
if (found) return (enum parseKey) midpoint;
|
||||
else return NOPE;
|
||||
|
||||
} /* recognize */
|
||||
|
||||
|
||||
/************************* parseGlobals *****************************/
|
||||
|
||||
static BOOL parseGlobals(fp, gfi)
|
||||
FILE *fp;
|
||||
register PS_FontInfo *gfi;
|
||||
{
|
||||
BOOL cont = 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 = FALSE;
|
||||
break;
|
||||
case ENDFONTMETRICS:
|
||||
cont = 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);
|
||||
break;
|
||||
case COMMENT:
|
||||
keyword = linetoken(fp);
|
||||
break;
|
||||
case FONTNAME:
|
||||
keyword = token(fp);
|
||||
gfi->name = (char *) malloc(strlen(keyword) + 1);
|
||||
strcpy(gfi->name, keyword);
|
||||
break;
|
||||
case ENCODINGSCHEME:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case FULLNAME:
|
||||
keyword = linetoken(fp);
|
||||
break;
|
||||
case FAMILYNAME:
|
||||
keyword = linetoken(fp);
|
||||
break;
|
||||
case WEIGHT:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case ITALICANGLE:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case ISFIXEDPITCH:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case UNDERLINEPOSITION:
|
||||
keyword = token(fp);
|
||||
gfi->upos = atoi(keyword);
|
||||
break;
|
||||
case UNDERLINETHICKNESS:
|
||||
keyword = token(fp);
|
||||
gfi->uthick = atoi(keyword);
|
||||
break;
|
||||
case VERSION:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case NOTICE:
|
||||
keyword = linetoken(fp);
|
||||
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);
|
||||
break;
|
||||
case XHEIGHT:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case DESCENDER:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case ASCENDER:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case STARTCHARMETRICS:
|
||||
cont = FALSE;
|
||||
break;
|
||||
case ENDFONTMETRICS:
|
||||
cont = FALSE;
|
||||
error = normalEOF;
|
||||
break;
|
||||
case NOPE:
|
||||
break;
|
||||
default:
|
||||
error = parseError;
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
} /* while */
|
||||
|
||||
return(error);
|
||||
|
||||
} /* parseGlobals */
|
||||
|
||||
/************************* parseCharMetrics ************************/
|
||||
|
||||
static int parseCharMetrics(fp, fi)
|
||||
FILE *fp;
|
||||
register PS_FontInfo *fi;
|
||||
{
|
||||
BOOL cont = TRUE;
|
||||
int error = ok, count = 0, code = 0;
|
||||
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:
|
||||
code = atoi(token(fp));
|
||||
count++;
|
||||
break;
|
||||
case XYWIDTH:
|
||||
if (code <0 || code >= 256) {
|
||||
token(fp); token(fp); break;
|
||||
}
|
||||
fi->chars[code].wx = atoi(token(fp));
|
||||
fi->chars[code].wy = atoi(token(fp));
|
||||
break;
|
||||
case XWIDTH:
|
||||
if (code <0 || code >= 256) {
|
||||
token(fp); break;
|
||||
}
|
||||
fi->chars[code].wx = atoi(token(fp));
|
||||
break;
|
||||
case CHARNAME:
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case CHARBBOX:
|
||||
if (code <0 || code >= 256) {
|
||||
token(fp); token(fp); token(fp); token(fp); break;
|
||||
}
|
||||
fi->chars[code].charBBox.llx = atoi(token(fp));
|
||||
fi->chars[code].charBBox.lly = atoi(token(fp));
|
||||
fi->chars[code].charBBox.urx = atoi(token(fp));
|
||||
fi->chars[code].charBBox.ury = atoi(token(fp));
|
||||
break;
|
||||
case LIGATURE:
|
||||
keyword = token(fp);
|
||||
keyword = token(fp);
|
||||
break;
|
||||
case ENDCHARMETRICS:
|
||||
cont = FALSE;;
|
||||
break;
|
||||
case ENDFONTMETRICS:
|
||||
cont = FALSE;
|
||||
error = normalEOF;
|
||||
break;
|
||||
case NOPE:
|
||||
break;
|
||||
default:
|
||||
error = parseError;
|
||||
break;
|
||||
} /* switch */
|
||||
} /* while */
|
||||
|
||||
return(error);
|
||||
|
||||
} /* parseCharMetrics */
|
||||
|
||||
|
||||
|
||||
/*************************** 'PUBLIC' FUNCTION ********************/
|
||||
|
||||
|
||||
/*************************** XP_parseAFMFile *****************************/
|
||||
|
||||
/* this is the only 'public' procedure available. It is called
|
||||
* from an application wishing to get information from an AFM file.
|
||||
* The caller of this function is responsible for locating and opening
|
||||
* an AFM file and handling all errors associated with that task.
|
||||
*
|
||||
* parseFile returns an error code as defined in parseAFM.h.
|
||||
*
|
||||
* The position of the read/write pointer associated with the file
|
||||
* pointer upon return of this function is undefined.
|
||||
*/
|
||||
|
||||
int XP_parseAFMFile (fp, fi)
|
||||
FILE *fp;
|
||||
PS_FontInfo **fi;
|
||||
{
|
||||
|
||||
int code = ok; /* return code from each of the parsing routines */
|
||||
int error = ok; /* used as the return code from this function */
|
||||
int i;
|
||||
|
||||
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);}
|
||||
|
||||
if ((*fi) == NULL) (*fi) = (PS_FontInfo *) calloc(1, sizeof(PS_FontInfo));
|
||||
if ((*fi) == NULL) {error = storageProblem; return(error);}
|
||||
|
||||
for (i=0; i<256; i++) { /* initialize the default font width */
|
||||
(*fi)->chars[i].wx = 250;
|
||||
}
|
||||
|
||||
/* The AFM File begins with Global Font Information. This section */
|
||||
/* will be parsed whether or not information should be saved. */
|
||||
code = parseGlobals(fp, (*fi));
|
||||
|
||||
/* be liberal to strict AFM grammar. */
|
||||
if ((code != earlyEOF) && (code < 0)) error = code;
|
||||
|
||||
/* The Global Font Information is followed by the Character Metrics */
|
||||
/* section. */
|
||||
|
||||
if ((code != normalEOF) && (code != earlyEOF))
|
||||
{
|
||||
token(fp);
|
||||
code = parseCharMetrics(fp, *fi);
|
||||
} /* if */
|
||||
|
||||
if ((code != earlyEOF) && (code < 0)) error = code;
|
||||
|
||||
if (ident != NULL) { free(ident); ident = NULL; }
|
||||
|
||||
return(error);
|
||||
|
||||
} /* XP_parseAFMFile */
|
303
lib/xlate/parseAFM.h
Normal file
303
lib/xlate/parseAFM.h
Normal file
@ -0,0 +1,303 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* (C) 1988, 1989 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.h
|
||||
*
|
||||
* This header file is used in conjuction with the parseAFM.c file.
|
||||
* Together these files provide the functionality to parse Adobe Font
|
||||
* Metrics files and store the information in predefined data structures.
|
||||
* 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
|
||||
* parse an AFM file and have the data stored, or an application developer
|
||||
* may wish to customize the code.
|
||||
*
|
||||
* This header file defines the data structures used as well as the key
|
||||
* strings that are currently recognized by this version of the AFM parser.
|
||||
* This program is based on the document "Adobe Font Metrics Files,
|
||||
* Specification Version 2.0".
|
||||
*
|
||||
* AFM files are separated into distinct sections of different data. Because
|
||||
* of this, the parseAFM program can parse a specified file to only save
|
||||
* certain sections of information based on the application's needs. A record
|
||||
* containing the requested information will be returned to the application.
|
||||
*
|
||||
* AFM files are divided into five sections of data:
|
||||
* 1) The Global Font Information
|
||||
* 2) The Character Metrics Information
|
||||
* 3) The Track Kerning Data
|
||||
* 4) The Pair-Wise Kerning Data
|
||||
* 5) The Composite Character Data
|
||||
*
|
||||
* Basically, the application can request any of these sections independent
|
||||
* of what other sections are requested. In addition, in recognizing that
|
||||
* many applications will want ONLY the x-width of characters and not all
|
||||
* of the other character metrics information, there is a way to receive
|
||||
* only the width information so as not to pay the storage cost for the
|
||||
* unwanted data. An application should never request both the
|
||||
* "quick and dirty" char metrics (widths only) and the Character Metrics
|
||||
* Information since the Character Metrics Information will contain all
|
||||
* of the character widths as well.
|
||||
*
|
||||
* There is a procedure in parseAFM.c, called parseFile, that can be
|
||||
* called from any application wishing to get information from the AFM File.
|
||||
* This procedure expects 3 parameters: a vaild file descriptor, a pointer
|
||||
* to a (FontInfo *) variable (for which space will be allocated and then
|
||||
* will be filled in with the data requested), and a mask specifying
|
||||
* which data from the AFM File should be saved in the FontInfo structure.
|
||||
*
|
||||
* The flags that can be used to set the appropriate mask are defined below.
|
||||
* In addition, several commonly used masks have already been defined.
|
||||
*
|
||||
* 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 typos
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* your basic constants */
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#define EOL '\n' /* end-of-line indicator */
|
||||
#define MAX_NAME 4096 /* max length for identifiers */
|
||||
#define BOOL int
|
||||
#define FLAGS int
|
||||
|
||||
|
||||
|
||||
/* Flags that can be AND'ed together to specify exactly what
|
||||
* information from the AFM file should be saved.
|
||||
*/
|
||||
#define P_G 0x01 /* 0000 0001 */ /* Global Font Info */
|
||||
#define P_W 0x02 /* 0000 0010 */ /* Character Widths ONLY */
|
||||
#define P_M 0x06 /* 0000 0110 */ /* All Char Metric Info */
|
||||
#define P_P 0x08 /* 0000 1000 */ /* Pair Kerning Info */
|
||||
#define P_T 0x10 /* 0001 0000 */ /* Track Kerning Info */
|
||||
#define P_C 0x20 /* 0010 0000 */ /* Composite Char Info */
|
||||
|
||||
|
||||
/* Commonly used flags
|
||||
*/
|
||||
#define P_GW (P_G | P_W)
|
||||
#define P_GM (P_G | P_M)
|
||||
#define P_GMP (P_G | P_M | P_P)
|
||||
#define P_GMK (P_G | P_M | P_P | P_T)
|
||||
#define P_ALL (P_G | P_M | P_P | P_T | P_C)
|
||||
|
||||
|
||||
|
||||
/* Possible return codes from the parseFile procedure.
|
||||
*
|
||||
* ok means there were no problems parsing the file.
|
||||
*
|
||||
* parseError means that there was some kind of parsing error, but the
|
||||
* parser went on. This could include problems like the count for any given
|
||||
* section does not add up to how many entries there actually were, or
|
||||
* there was a key that was not recognized. The return record may contain
|
||||
* vaild data or it may not.
|
||||
*
|
||||
* earlyEOF means that an End of File was encountered before expected. This
|
||||
* may mean that the AFM file had been truncated, or improperly formed.
|
||||
*
|
||||
* storageProblem means that there were problems allocating storage for
|
||||
* the data structures that would have contained the AFM data.
|
||||
*/
|
||||
#define ok 0
|
||||
#define parseError -1
|
||||
#define earlyEOF -2
|
||||
#define storageProblem -3
|
||||
|
||||
|
||||
|
||||
/************************* TYPES *********************************/
|
||||
/* Below are all of the data structure definitions. These structures
|
||||
* try to map as closely as possible to grouping and naming of data
|
||||
* in the AFM Files.
|
||||
*/
|
||||
|
||||
|
||||
/* Bounding box definition. Used for the Font BBox as well as the
|
||||
* Character BBox.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int llx; /* lower left x-position */
|
||||
int lly; /* lower left y-position */
|
||||
int urx; /* upper right x-position */
|
||||
int ury; /* upper right y-position */
|
||||
} BBox;
|
||||
|
||||
|
||||
/* Global Font information.
|
||||
* The key that each field is associated with is in comments. For an
|
||||
* explanation about each key and its value please refer to the AFM
|
||||
* documentation (full title & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *afmVersion; /* key: StartFontMetrics */
|
||||
char *fontName; /* key: FontName */
|
||||
char *fullName; /* key: FullName */
|
||||
char *familyName; /* key: FamilyName */
|
||||
char *weight; /* key: Weight */
|
||||
float italicAngle; /* key: ItalicAngle */
|
||||
BOOL isFixedPitch; /* key: IsFixedPitch */
|
||||
BBox fontBBox; /* key: FontBBox */
|
||||
int underlinePosition; /* key: UnderlinePosition */
|
||||
int underlineThickness; /* key: UnderlineThickness */
|
||||
char *version; /* key: Version */
|
||||
char *notice; /* key: Notice */
|
||||
char *encodingScheme; /* key: EncodingScheme */
|
||||
int capHeight; /* key: CapHeight */
|
||||
int xHeight; /* key: XHeight */
|
||||
int ascender; /* key: Ascender */
|
||||
int descender; /* key: Descender */
|
||||
} GlobalFontInfo;
|
||||
|
||||
|
||||
/* Ligature definition is a linked list since any character can have
|
||||
* any number of ligatures.
|
||||
*/
|
||||
typedef struct _t_ligature
|
||||
{
|
||||
char *succ, *lig;
|
||||
struct _t_ligature *next;
|
||||
} Ligature;
|
||||
|
||||
|
||||
/* Character Metric Information. This structure is used only if ALL
|
||||
* character metric information is requested. If only the character
|
||||
* widths is requested, then only an array of the character x-widths
|
||||
* is returned.
|
||||
*
|
||||
* The key that each field is associated with is in comments. For an
|
||||
* explanation about each key and its value please refer to the
|
||||
* Character Metrics section of the AFM documentation (full title
|
||||
* & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int code, /* key: C */
|
||||
wx, /* key: WX */
|
||||
wy; /* together wx and wy are associated with key: W */
|
||||
char *name; /* key: N */
|
||||
BBox charBBox; /* key: B */
|
||||
Ligature *ligs; /* key: L (linked list; not a fixed number of Ls */
|
||||
} CharMetricInfo;
|
||||
|
||||
|
||||
/* Track kerning data structure.
|
||||
* The fields of this record are the five values associated with every
|
||||
* TrackKern entry.
|
||||
*
|
||||
* For an explanation about each value please refer to the
|
||||
* Track Kerning section of the AFM documentation (full title
|
||||
* & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int degree;
|
||||
float minPtSize,
|
||||
minKernAmt,
|
||||
maxPtSize,
|
||||
maxKernAmt;
|
||||
} TrackKernData;
|
||||
|
||||
|
||||
/* Pair Kerning data structure.
|
||||
* The fields of this record are the four values associated with every
|
||||
* KP entry. For KPX entries, the yamt will be zero.
|
||||
*
|
||||
* For an explanation about each value please refer to the
|
||||
* Pair Kerning section of the AFM documentation (full title
|
||||
* & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *name1;
|
||||
char *name2;
|
||||
int xamt,
|
||||
yamt;
|
||||
} PairKernData;
|
||||
|
||||
|
||||
/* PCC is a piece of a composite character. This is a sub structure of a
|
||||
* compCharData described below.
|
||||
* These fields will be filled in with the values from the key PCC.
|
||||
*
|
||||
* For an explanation about each key and its value please refer to the
|
||||
* Composite Character section of the AFM documentation (full title
|
||||
* & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *pccName;
|
||||
int deltax,
|
||||
deltay;
|
||||
} Pcc;
|
||||
|
||||
|
||||
/* Composite Character Information data structure.
|
||||
* The fields ccName and numOfPieces are filled with the values associated
|
||||
* with the key CC. The field pieces points to an array (size = numOfPieces)
|
||||
* of information about each of the parts of the composite character. That
|
||||
* array is filled in with the values from the key PCC.
|
||||
*
|
||||
* For an explanation about each key and its value please refer to the
|
||||
* Composite Character section of the AFM documentation (full title
|
||||
* & version given above).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char *ccName;
|
||||
int numOfPieces;
|
||||
Pcc *pieces;
|
||||
} CompCharData;
|
||||
|
||||
|
||||
/* FontInfo
|
||||
* Record type containing pointers to all of the other data
|
||||
* structures containing information about a font.
|
||||
* A a record of this type is filled with data by the
|
||||
* parseFile function.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
GlobalFontInfo *gfi; /* ptr to a GlobalFontInfo record */
|
||||
int *cwi; /* ptr to 256 element array of just char widths */
|
||||
int numOfChars; /* number of entries in char metrics array */
|
||||
CharMetricInfo *cmi; /* ptr to char metrics array */
|
||||
int numOfTracks; /* number to entries in track kerning array */
|
||||
TrackKernData *tkd; /* ptr to track kerning array */
|
||||
int numOfPairs; /* number to entries in pair kerning array */
|
||||
PairKernData *pkd; /* ptr to pair kerning array */
|
||||
int numOfComps; /* number to entries in comp char array */
|
||||
CompCharData *ccd; /* ptr to comp char array */
|
||||
} FontInfo;
|
||||
|
Loading…
x
Reference in New Issue
Block a user