1 /* Modified 1999 Morten Welinder: 2 * 1. ANSI prototype. 3 * 2. parseFileFree function. 4 */ 5 6 /* 7 * (C) 1988, 1989 by Adobe Systems Incorporated. All rights reserved. 8 * 9 * This file may be freely copied and redistributed as long as: 10 * 1) This entire notice continues to be included in the file, 11 * 2) If the file has been modified in any way, a notice of such 12 * modification is conspicuously indicated. 13 * 14 * PostScript, Display PostScript, and Adobe are registered trademarks of 15 * Adobe Systems Incorporated. 16 * 17 * ************************************************************************ 18 * THE INFORMATION BELOW IS FURNISHED AS IS, IS SUBJECT TO CHANGE WITHOUT 19 * NOTICE, AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY ADOBE SYSTEMS 20 * INCORPORATED. ADOBE SYSTEMS INCORPORATED ASSUMES NO RESPONSIBILITY OR 21 * LIABILITY FOR ANY ERRORS OR INACCURACIES, MAKES NO WARRANTY OF ANY 22 * KIND (EXPRESS, IMPLIED OR STATUTORY) WITH RESPECT TO THIS INFORMATION, 23 * AND EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES OF MERCHANTABILITY, 24 * FITNESS FOR PARTICULAR PURPOSES AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. 25 * ************************************************************************ 26 */ 27 28 /* ParseAFM.h 29 * 30 * This header file is used in conjuction with the parseAFM.c file. 31 * Together these files provide the functionality to parse Adobe Font 32 * Metrics files and store the information in predefined data structures. 33 * It is intended to work with an application program that needs font metric 34 * information. The program can be used as is by making a procedure call to 35 * parse an AFM file and have the data stored, or an application developer 36 * may wish to customize the code. 37 * 38 * This header file defines the data structures used as well as the key 39 * strings that are currently recognized by this version of the AFM parser. 40 * This program is based on the document "Adobe Font Metrics Files, 41 * Specification Version 2.0". 42 * 43 * AFM files are separated into distinct sections of different data. Because 44 * of this, the parseAFM program can parse a specified file to only save 45 * certain sections of information based on the application's needs. A record 46 * containing the requested information will be returned to the application. 47 * 48 * AFM files are divided into five sections of data: 49 * 1) The Global Font Information 50 * 2) The Character Metrics Information 51 * 3) The Track Kerning Data 52 * 4) The Pair-Wise Kerning Data 53 * 5) The Composite Character Data 54 * 55 * Basically, the application can request any of these sections independent 56 * of what other sections are requested. In addition, in recognizing that 57 * many applications will want ONLY the x-width of characters and not all 58 * of the other character metrics information, there is a way to receive 59 * only the width information so as not to pay the storage cost for the 60 * unwanted data. An application should never request both the 61 * "quick and dirty" char metrics (widths only) and the Character Metrics 62 * Information since the Character Metrics Information will contain all 63 * of the character widths as well. 64 * 65 * There is a procedure in parseAFM.c, called parseFile, that can be 66 * called from any application wishing to get information from the AFM File. 67 * This procedure expects 3 parameters: a vaild file descriptor, a pointer 68 * to a (FontInfo *) variable (for which space will be allocated and then 69 * will be filled in with the data requested), and a mask specifying 70 * which data from the AFM File should be saved in the FontInfo structure. 71 * 72 * The flags that can be used to set the appropriate mask are defined below. 73 * In addition, several commonly used masks have already been defined. 74 * 75 * History: 76 * original: DSM Thu Oct 20 17:39:59 PDT 1988 77 * modified: DSM Mon Jul 3 14:17:50 PDT 1989 78 * - added 'storageProblem' return code 79 * - fixed typos 80 */ 81 82 #include <stdio.h> 83 84 85 86 /* your basic constants */ 87 #undef TRUE 88 #define TRUE 1 89 #undef FALSE 90 #define FALSE 0 91 #define EOL '\n' /* end-of-line indicator */ 92 #define MAX_NAME 4096 /* max length for identifiers */ 93 #define BOOL int 94 #define FLAGS int 95 96 97 98 /* Flags that can be AND'ed together to specify exactly what 99 * information from the AFM file should be saved. 100 */ 101 #define P_G 0x01 /* 0000 0001 */ /* Global Font Info */ 102 #define P_W 0x02 /* 0000 0010 */ /* Character Widths ONLY */ 103 #define P_M 0x06 /* 0000 0110 */ /* All Char Metric Info */ 104 #define P_P 0x08 /* 0000 1000 */ /* Pair Kerning Info */ 105 #define P_T 0x10 /* 0001 0000 */ /* Track Kerning Info */ 106 #define P_C 0x20 /* 0010 0000 */ /* Composite Char Info */ 107 108 109 /* Commonly used flags 110 */ 111 #define P_GW (P_G | P_W) 112 #define P_GM (P_G | P_M) 113 #define P_GMP (P_G | P_M | P_P) 114 #define P_GMK (P_G | P_M | P_P | P_T) 115 #define P_GALL (P_G | P_M | P_P | P_T | P_C) 116 117 118 119 /* Possible return codes from the parseFile procedure. 120 * 121 * ok means there were no problems parsing the file. 122 * 123 * parseError means that there was some kind of parsing error, but the 124 * parser went on. This could include problems like the count for any given 125 * section does not add up to how many entries there actually were, or 126 * there was a key that was not recognized. The return record may contain 127 * vaild data or it may not. 128 * 129 * earlyEOF means that an End of File was encountered before expected. This 130 * may mean that the AFM file had been truncated, or improperly formed. 131 * 132 * storageProblem means that there were problems allocating storage for 133 * the data structures that would have contained the AFM data. 134 */ 135 #define AFM_ok 0 136 #define AFM_parseError -1 137 #define AFM_earlyEOF -2 138 #define AFM_storageProblem -3 139 140 141 142 /************************* TYPES *********************************/ 143 /* Below are all of the data structure definitions. These structures 144 * try to map as closely as possible to grouping and naming of data 145 * in the AFM Files. 146 */ 147 148 149 /* Bounding box definition. Used for the Font BBox as well as the 150 * Character BBox. 151 */ 152 typedef struct 153 { 154 int llx; /* lower left x-position */ 155 int lly; /* lower left y-position */ 156 int urx; /* upper right x-position */ 157 int ury; /* upper right y-position */ 158 } BBox; 159 160 161 /* Global Font information. 162 * The key that each field is associated with is in comments. For an 163 * explanation about each key and its value please refer to the AFM 164 * documentation (full title & version given above). 165 */ 166 typedef struct 167 { 168 char *afmVersion; /* key: StartFontMetrics */ 169 char *fontName; /* key: FontName */ 170 char *fullName; /* key: FullName */ 171 char *familyName; /* key: FamilyName */ 172 char *weight; /* key: Weight */ 173 float italicAngle; /* key: ItalicAngle */ 174 BOOL isFixedPitch; /* key: IsFixedPitch */ 175 BBox fontBBox; /* key: FontBBox */ 176 int underlinePosition; /* key: UnderlinePosition */ 177 int underlineThickness; /* key: UnderlineThickness */ 178 char *version; /* key: Version */ 179 char *notice; /* key: Notice */ 180 char *encodingScheme; /* key: EncodingScheme */ 181 int capHeight; /* key: CapHeight */ 182 int xHeight; /* key: XHeight */ 183 int ascender; /* key: Ascender */ 184 int descender; /* key: Descender */ 185 } GlobalFontInfo; 186 187 188 /* Ligature definition is a linked list since any character can have 189 * any number of ligatures. 190 */ 191 typedef struct _t_ligature 192 { 193 char *succ, *lig; 194 struct _t_ligature *next; 195 } Ligature; 196 197 198 /* Character Metric Information. This structure is used only if ALL 199 * character metric information is requested. If only the character 200 * widths is requested, then only an array of the character x-widths 201 * is returned. 202 * 203 * The key that each field is associated with is in comments. For an 204 * explanation about each key and its value please refer to the 205 * Character Metrics section of the AFM documentation (full title 206 * & version given above). 207 */ 208 typedef struct 209 { 210 int code, /* key: C */ 211 wx, /* key: WX */ 212 wy; /* together wx and wy are associated with key: W */ 213 char *name; /* key: N */ 214 BBox charBBox; /* key: B */ 215 Ligature *ligs; /* key: L (linked list; not a fixed number of Ls */ 216 } CharMetricInfo; 217 218 219 /* Track kerning data structure. 220 * The fields of this record are the five values associated with every 221 * TrackKern entry. 222 * 223 * For an explanation about each value please refer to the 224 * Track Kerning section of the AFM documentation (full title 225 * & version given above). 226 */ 227 typedef struct 228 { 229 int degree; 230 float minPtSize, 231 minKernAmt, 232 maxPtSize, 233 maxKernAmt; 234 } TrackKernData; 235 236 237 /* Pair Kerning data structure. 238 * The fields of this record are the four values associated with every 239 * KP entry. For KPX entries, the yamt will be zero. 240 * 241 * For an explanation about each value please refer to the 242 * Pair Kerning section of the AFM documentation (full title 243 * & version given above). 244 */ 245 typedef struct 246 { 247 char *name1; 248 char *name2; 249 int xamt, 250 yamt; 251 } PairKernData; 252 253 254 /* PCC is a piece of a composite character. This is a sub structure of a 255 * compCharData described below. 256 * These fields will be filled in with the values from the key PCC. 257 * 258 * For an explanation about each key and its value please refer to the 259 * Composite Character section of the AFM documentation (full title 260 * & version given above). 261 */ 262 typedef struct 263 { 264 char *pccName; 265 int deltax, 266 deltay; 267 } Pcc; 268 269 270 /* Composite Character Information data structure. 271 * The fields ccName and numOfPieces are filled with the values associated 272 * with the key CC. The field pieces points to an array (size = numOfPieces) 273 * of information about each of the parts of the composite character. That 274 * array is filled in with the values from the key PCC. 275 * 276 * For an explanation about each key and its value please refer to the 277 * Composite Character section of the AFM documentation (full title 278 * & version given above). 279 */ 280 typedef struct 281 { 282 char *ccName; 283 int numOfPieces; 284 Pcc *pieces; 285 } CompCharData; 286 287 288 /* FontInfo 289 * Record type containing pointers to all of the other data 290 * structures containing information about a font. 291 * A a record of this type is filled with data by the 292 * parseFile function. 293 */ 294 typedef struct 295 { 296 GlobalFontInfo *gfi; /* ptr to a GlobalFontInfo record */ 297 int *cwi; /* ptr to 256 element array of just char widths */ 298 int numOfChars; /* number of entries in char metrics array */ 299 CharMetricInfo *cmi; /* ptr to char metrics array */ 300 int numOfTracks; /* number to entries in track kerning array */ 301 TrackKernData *tkd; /* ptr to track kerning array */ 302 int numOfPairs; /* number to entries in pair kerning array */ 303 PairKernData *pkd; /* ptr to pair kerning array */ 304 int numOfComps; /* number to entries in comp char array */ 305 CompCharData *ccd; /* ptr to comp char array */ 306 } Font_Info; 307 308 309 310 /************************* PROCEDURES ****************************/ 311 312 /* Call this procedure to do the grunt work of parsing an AFM file. 313 * 314 * "fp" should be a valid file pointer to an AFM file. 315 * 316 * "fi" is a pointer to a pointer to a FontInfo record sturcture 317 * (defined above). Storage for the FontInfo structure will be 318 * allocated in parseFile and the structure will be filled in 319 * with the requested data from the AFM File. 320 * 321 * "flags" is a mask with bits set representing what data should 322 * be saved. Defined above are valid flags that can be used to set 323 * the mask, as well as a few commonly used masks. 324 * 325 * The possible return codes from parseFile are defined above. 326 */ 327 328 int parseFile (FILE *fp, Font_Info **fi, FLAGS flags); 329 void parseFileFree (Font_Info *fi); 330