From f4092abdf94af6a99aff944d6264bc1284e8bdd4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 10 Oct 2011 17:43:39 +0200 Subject: Imported nx-X11-3.1.0-1.tar.gz Summary: Imported nx-X11-3.1.0-1.tar.gz Keywords: Imported nx-X11-3.1.0-1.tar.gz into Git repository --- nx-X11/lib/font/Type1/scanfont.c | 2370 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 2370 insertions(+) create mode 100644 nx-X11/lib/font/Type1/scanfont.c (limited to 'nx-X11/lib/font/Type1/scanfont.c') diff --git a/nx-X11/lib/font/Type1/scanfont.c b/nx-X11/lib/font/Type1/scanfont.c new file mode 100644 index 000000000..8db497959 --- /dev/null +++ b/nx-X11/lib/font/Type1/scanfont.c @@ -0,0 +1,2370 @@ +/* $XdotOrg: xc/lib/font/Type1/scanfont.c,v 1.5 2005/07/09 23:30:06 keithp Exp $ */ +/* $Xorg: scanfont.c,v 1.3 2000/08/17 19:46:32 cpqbld Exp $ */ +/* Copyright International Business Machines,Corp. 1991 + * All Rights Reserved + * + * License to use, copy, modify, and distribute this software + * and its documentation for any purpose and without fee is + * hereby granted, provided that the above copyright notice + * appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, + * and that the name of IBM not be used in advertising or + * publicity pertaining to distribution of the software without + * specific, written prior permission. + * + * IBM PROVIDES THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES + * OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT + * LIMITED TO ANY IMPLIED WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. THE ENTIRE RISK AS TO THE QUALITY AND + * PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT + * OR MAINTAIN, BELONGS TO THE LICENSEE. SHOULD ANY PORTION OF + * THE SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM) ASSUMES + * THE ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION. IN + * NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ +/* Author: Katherine A. Hitchcock IBM Almaden Research Laboratory */ +/* Copyright (c) 1994-1999 Silicon Graphics, Inc. All Rights Reserved. + * + * The contents of this file are subject to the CID Font Code Public Licence + * Version 1.0 (the "License"). You may not use this file except in compliance + * with the Licence. You may obtain a copy of the License at Silicon Graphics, + * Inc., attn: Legal Services, 2011 N. Shoreline Blvd., Mountain View, CA + * 94043 or at http://www.sgi.com/software/opensource/cid/license.html. + * + * Software distributed under the License is distributed on an "AS IS" basis. + * ALL WARRANTIES ARE DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR PURPOSE OR OF + * NON-INFRINGEMENT. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Software is CID font code that was developed by Silicon + * Graphics, Inc. + */ +/* $XFree86: xc/lib/font/Type1/scanfont.c,v 1.16 2003/05/27 22:26:46 tsi Exp $ */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#ifdef BUILDCID +#define XFONT_CID 1 +#endif + +#ifndef FONTMODULE +#include +#include +#else +#include "Xdefs.h" /* Bool declaration */ +#include "Xmd.h" /* INT32 declaration */ +#include "xf86_ansic.h" +#endif +#include "t1stdio.h" +#include "util.h" +#include "token.h" +#if XFONT_CID +#include "range.h" +#endif +#include "objects.h" +#include "spaces.h" +#include "fontfcn.h" +#include "blues.h" + +#if XFONT_CID +#define CID_BUFSIZE 80 + +extern psfont *FDArrayP; +static spacerange *spacerangeP; +static cidrange *notdefrangeP; +static cidrange *cidrangeP; +extern int FDArrayIndex; +static boolean CIDWantFontInfo; +static psobj inputFile1; +#endif + +static int rc; +static boolean InPrivateDict; +static boolean WantFontInfo; +static boolean TwoSubrs; +static psobj inputFile; +static psobj filterFile; +static psobj *inputP; + + +/**********************************************************************/ +/* Init_BuiltInEncoding() */ +/* */ +/* Initializes the StandardEncoding and ISOLatin1Encoding vector. */ +/* */ +/**********************************************************************/ +typedef struct /* Builtin Standard Encoding */ +{ + int index; + char *name; +} EncodingTable; + +static EncodingTable StdEnc[] = { + { 040 , "space" }, + { 041 , "exclam" }, + { 042 , "quotedbl" }, + { 043 , "numbersign" }, + { 044 , "dollar" }, + { 045 , "percent" }, + { 046 , "ampersand" }, + { 047 , "quoteright" }, + { 050 , "parenleft" }, + { 051 , "parenright" }, + { 052 , "asterisk" }, + { 053 , "plus" }, + { 054 , "comma" }, + { 055 , "hyphen" }, + { 056 , "period" }, + { 057 , "slash" }, + { 060 , "zero" }, + { 061 , "one" }, + { 062 , "two" }, + { 063 , "three" }, + { 064 , "four" }, + { 065 , "five" }, + { 066 , "six" }, + { 067 , "seven" }, + { 070 , "eight" }, + { 071 , "nine" }, + { 072 , "colon" }, + { 073 , "semicolon" }, + { 074 , "less" }, + { 075 , "equal" }, + { 076 , "greater" }, + { 077 , "question" }, + { 0100 , "at" }, + { 0101 , "A" }, + { 0102 , "B" }, + { 0103 , "C" }, + { 0104 , "D" }, + { 0105 , "E" }, + { 0106 , "F" }, + { 0107 , "G" }, + { 0110 , "H" }, + { 0111 , "I" }, + { 0112 , "J" }, + { 0113 , "K" }, + { 0114 , "L" }, + { 0115 , "M" }, + { 0116 , "N" }, + { 0117 , "O" }, + { 0120 , "P" }, + { 0121 , "Q" }, + { 0122 , "R" }, + { 0123 , "S" }, + { 0124 , "T" }, + { 0125 , "U" }, + { 0126 , "V" }, + { 0127 , "W" }, + { 0130 , "X" }, + { 0131 , "Y" }, + { 0132 , "Z" }, + { 0133 , "bracketleft" }, + { 0134 , "backslash" }, + { 0135 , "bracketright" }, + { 0136 , "asciicircum" }, + { 0137 , "underscore" }, + { 0140 , "quoteleft" }, + { 0141 , "a" }, + { 0142 , "b" }, + { 0143 , "c" }, + { 0144 , "d" }, + { 0145 , "e" }, + { 0146 , "f" }, + { 0147 , "g" }, + { 0150 , "h" }, + { 0151 , "i" }, + { 0152 , "j" }, + { 0153 , "k" }, + { 0154 , "l" }, + { 0155 , "m" }, + { 0156 , "n" }, + { 0157 , "o" }, + { 0160 , "p" }, + { 0161 , "q" }, + { 0162 , "r" }, + { 0163 , "s" }, + { 0164 , "t" }, + { 0165 , "u" }, + { 0166 , "v" }, + { 0167 , "w" }, + { 0170 , "x" }, + { 0171 , "y" }, + { 0172 , "z" }, + { 0173 , "braceleft" }, + { 0174 , "bar" }, + { 0175 , "braceright" }, + { 0176 , "asciitilde" }, + { 0241 , "exclamdown" }, + { 0242 , "cent" }, + { 0243 , "sterling" }, + { 0244 , "fraction" }, + { 0245 , "yen" }, + { 0246 , "florin" }, + { 0247 , "section" }, + { 0250 , "currency" }, + { 0251 , "quotesingle" }, + { 0252 , "quotedblleft" }, + { 0253 , "guillemotleft" }, + { 0254 , "guilsinglleft" }, + { 0255 , "guilsinglright" }, + { 0256 , "fi" }, + { 0257 , "fl" }, + { 0261 , "endash" }, + { 0262 , "dagger" }, + { 0263 , "daggerdbl" }, + { 0264 , "periodcentered" }, + { 0266 , "paragraph" }, + { 0267 , "bullet" }, + { 0270 , "quotesinglbase" }, + { 0271 , "quotedblbase" }, + { 0272 , "quotedblright" }, + { 0273 , "guillemotright" }, + { 0274 , "ellipsis" }, + { 0275 , "perthousand" }, + { 0277 , "questiondown" }, + { 0301 , "grave" }, + { 0302 , "acute" }, + { 0303 , "circumflex" }, + { 0304 , "tilde" }, + { 0305 , "macron" }, + { 0306 , "breve" }, + { 0307 , "dotaccent" }, + { 0310 , "dieresis" }, + { 0312 , "ring" }, + { 0313 , "cedilla" }, + { 0315 , "hungarumlaut" }, + { 0316 , "ogonek" }, + { 0317 , "caron" }, + { 0320 , "emdash" }, + { 0341 , "AE" }, + { 0343 , "ordfeminine" }, + { 0350 , "Lslash" }, + { 0351 , "Oslash" }, + { 0352 , "OE" }, + { 0353 , "ordmasculine" }, + { 0361 , "ae" }, + { 0365 , "dotlessi" }, + { 0370 , "lslash" }, + { 0371 , "oslash" }, + { 0372 , "oe" }, + { 0373 , "germandbls" }, + { 0, 0 } +}; + +static EncodingTable ISO8859Enc[] = { + { 32, "space" }, + { 33, "exclam" }, + { 34, "quotedbl" }, + { 35, "numbersign" }, + { 36, "dollar" }, + { 37, "percent" }, + { 38, "ampersand" }, + { 39, "quoteright" }, + { 40, "parenleft" }, + { 41, "parenright" }, + { 42, "asterisk" }, + { 43, "plus" }, + { 44, "comma" }, + { 45, "minus" }, + { 46, "period" }, + { 47, "slash" }, + { 48, "zero" }, + { 49, "one" }, + { 50, "two" }, + { 51, "three" }, + { 52, "four" }, + { 53, "five" }, + { 54, "six" }, + { 55, "seven" }, + { 56, "eight" }, + { 57, "nine" }, + { 58, "colon" }, + { 59, "semicolon" }, + { 60, "less" }, + { 61, "equal" }, + { 62, "greater" }, + { 63, "question" }, + { 64, "at" }, + { 65, "A" }, + { 66, "B" }, + { 67, "C" }, + { 68, "D" }, + { 69, "E" }, + { 70, "F" }, + { 71, "G" }, + { 72, "H" }, + { 73, "I" }, + { 74, "J" }, + { 75, "K" }, + { 76, "L" }, + { 77, "M" }, + { 78, "N" }, + { 79, "O" }, + { 80, "P" }, + { 81, "Q" }, + { 82, "R" }, + { 83, "S" }, + { 84, "T" }, + { 85, "U" }, + { 86, "V" }, + { 87, "W" }, + { 88, "X" }, + { 89, "Y" }, + { 90, "Z" }, + { 91, "bracketleft" }, + { 92, "backslash" }, + { 93, "bracketright" }, + { 94, "asciicircum" }, + { 95, "underscore" }, + { 96, "quoteleft" }, + { 97, "a" }, + { 98, "b" }, + { 99, "c" }, + { 100, "d" }, + { 101, "e" }, + { 102, "f" }, + { 103, "g" }, + { 104, "h" }, + { 105, "i" }, + { 106, "j" }, + { 107, "k" }, + { 108, "l" }, + { 109, "m" }, + { 110, "n" }, + { 111, "o" }, + { 112, "p" }, + { 113, "q" }, + { 114, "r" }, + { 115, "s" }, + { 116, "t" }, + { 117, "u" }, + { 118, "v" }, + { 119, "w" }, + { 120, "x" }, + { 121, "y" }, + { 122, "z" }, + { 123, "braceleft" }, + { 124, "bar" }, + { 125, "braceright" }, + { 126, "asciitilde" }, + { 160, "space" }, + { 161, "exclamdown" }, + { 162, "cent" }, + { 163, "sterling" }, + { 164, "currency" }, + { 165, "yen" }, + { 166, "brokenbar" }, + { 167, "section" }, + { 168, "dieresis" }, + { 169, "copyright" }, + { 170, "ordfeminine" }, + { 171, "guillemotleft" }, + { 172, "logicalnot" }, + { 173, "hyphen" }, + { 174, "registered" }, + { 175, "macron" }, + { 176, "degree" }, + { 177, "plusminus" }, + { 178, "twosuperior" }, + { 179, "threesuperior" }, + { 180, "acute" }, + { 181, "mu" }, + { 182, "paragraph" }, + { 183, "periodcentered" }, + { 184, "cedilla" }, + { 185, "onesuperior" }, + { 186, "ordmasculine" }, + { 187, "guillemotright" }, + { 188, "onequarter" }, + { 189, "onehalf" }, + { 190, "threequarters" }, + { 191, "questiondown" }, + { 192, "Agrave" }, + { 193, "Aacute" }, + { 194, "Acircumflex" }, + { 195, "Atilde" }, + { 196, "Adieresis" }, + { 197, "Aring" }, + { 198, "AE" }, + { 199, "Ccedilla" }, + { 200, "Egrave" }, + { 201, "Eacute" }, + { 202, "Ecircumflex" }, + { 203, "Edieresis" }, + { 204, "Igrave" }, + { 205, "Iacute" }, + { 206, "Icircumflex" }, + { 207, "Idieresis" }, + { 208, "Eth" }, + { 209, "Ntilde" }, + { 210, "Ograve" }, + { 211, "Oacute" }, + { 212, "Ocircumflex" }, + { 213, "Otilde" }, + { 214, "Odieresis" }, + { 215, "multiply" }, + { 216, "Oslash" }, + { 217, "Ugrave" }, + { 218, "Uacute" }, + { 219, "Ucircumflex" }, + { 220, "Udieresis" }, + { 221, "Yacute" }, + { 222, "Thorn" }, + { 223, "germandbls" }, + { 224, "agrave" }, + { 225, "aacute" }, + { 226, "acircumflex" }, + { 227, "atilde" }, + { 228, "adieresis" }, + { 229, "aring" }, + { 230, "ae" }, + { 231, "ccedilla" }, + { 232, "egrave" }, + { 233, "eacute" }, + { 234, "ecircumflex" }, + { 235, "edieresis" }, + { 236, "igrave" }, + { 237, "iacute" }, + { 238, "icircumflex" }, + { 239, "idieresis" }, + { 240, "eth" }, + { 241, "ntilde" }, + { 242, "ograve" }, + { 243, "oacute" }, + { 244, "ocircumflex" }, + { 245, "otilde" }, + { 246, "odieresis" }, + { 247, "divide" }, + { 248, "oslash" }, + { 249, "ugrave" }, + { 250, "uacute" }, + { 251, "ucircumflex" }, + { 252, "udieresis" }, + { 253, "yacute" }, + { 254, "thorn" }, + { 255, "ydieresis" }, + { 0, 0 } +}; + +static psobj *StdEncArrayP = NULL; +psobj *ISOLatin1EncArrayP = NULL; + +static psobj * +MakeEncodingArrayP(EncodingTable *encodingTable) +{ + int i; + psobj *encodingArrayP; + + encodingArrayP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!encodingArrayP) + return NULL; + + /* initialize everything to .notdef */ + for (i=0; i<256;i++) + objFormatName(&(encodingArrayP[i]),7, ".notdef"); + + for (i=0; encodingTable[i].name; i++) + { + objFormatName(&(encodingArrayP[encodingTable[i].index]), + strlen(encodingTable[i].name), + encodingTable[i].name); + } + + return(encodingArrayP); +} + +boolean +Init_BuiltInEncoding(void) +{ + StdEncArrayP = MakeEncodingArrayP(StdEnc); + ISOLatin1EncArrayP = MakeEncodingArrayP(ISO8859Enc); + return (StdEncArrayP && ISOLatin1EncArrayP); +} + +/********************************************************************/ +/***================================================================***/ +static int +getNextValue(int valueType) +{ + scan_token(inputP); + if (tokenType != valueType) { + return(SCAN_ERROR); + } + return(SCAN_OK); + +} +/***================================================================***/ +/* This routine will set the global rc if there is an error */ +/***================================================================***/ +static int +getInt(void) +{ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + return(0); + } + else { + return( tokenValue.integer); + } + +} +/***================================================================***/ +/* + * See Sec 10.3 of ``Adobe Type 1 Font Format'' v1.1, + * for parsing Encoding. + */ +static int +getEncoding(psobj *arrayP) +{ + scan_token(inputP); + if ((tokenType == TOKEN_NAME && (tokenLength==16 || tokenLength==17))) + { + if((tokenLength==16) && (!strncmp(tokenStartP,"StandardEncoding",16))) + arrayP->data.valueP = (char *) StdEncArrayP; + else + arrayP->data.valueP = (char *) ISOLatin1EncArrayP; + arrayP->len = 256; + return(SCAN_OK); + } + else if ( (tokenType == TOKEN_LEFT_BRACE) || + (tokenType == TOKEN_LEFT_BRACKET) ) + { + /* Array of literal names */ + + psobj *objP; + int i; + + objP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + arrayP->data.valueP = (char *) objP; + arrayP->len = 256; + + for (i=0; i<256; i++, objP++) + { + scan_token(inputP); + + if (tokenType != TOKEN_LITERAL_NAME) + return(SCAN_ERROR); + + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatName(objP,tokenLength,tokenStartP); + } + + scan_token(inputP); + if ( (tokenType == TOKEN_RIGHT_BRACE) || + (tokenType == TOKEN_RIGHT_BRACKET) ) + return(SCAN_OK); + } + else + { + /* Must be sequences of ``dup put" */ + + psobj *objP; + int i; + + objP = (psobj *)vm_alloc(256*(sizeof(psobj))); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + arrayP->data.valueP = (char *) objP; + arrayP->len = 256; + + for (i=0; i<256; i++) + objFormatName(objP + i, 7, ".notdef"); + + while (TRUE) + { + scan_token(inputP); + + switch (tokenType) + { + case TOKEN_NAME: + if (tokenLength == 3) + { + if (strncmp(tokenStartP,"dup",3) == 0) + { + /* get */ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER || + tokenValue.integer < 0 || + tokenValue.integer > 255) + return (SCAN_ERROR); + i = tokenValue.integer; + + /* get */ + scan_token(inputP); + if (tokenType != TOKEN_LITERAL_NAME) + return(SCAN_ERROR); + + if (!(vm_alloc(tokenLength)) ) + return(SCAN_OUT_OF_MEMORY); + objFormatName(objP + i,tokenLength,tokenStartP); + + /* get "put" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME) + return(SCAN_ERROR); + } + else if (strncmp(tokenStartP,"def",3) == 0) + return (SCAN_OK); + } + break; + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + return (SCAN_ERROR); + } + } + } + + return (SCAN_ERROR); +} +/***================================================================***/ +#if XFONT_CID +static int +getFDArray(psobj *arrayP) +{ + int rc; + + /* get the number of items in the FDArray */ + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) { + /* an FD array must contain at least one element */ + if (tokenValue.integer <= 0) + return(SCAN_ERROR); + arrayP->len = tokenValue.integer; + } else + return(SCAN_ERROR); + + /* get the token "array" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "array", 5) != 0) + return(SCAN_ERROR); + + /* format the array in memory, save pointer to the beginning */ + arrayP->data.valueP = tokenStartP; + + /* allocate FDArray */ + /* No integer overflow since arrayP->len is unsigned short */ + FDArrayP = (psfont *)vm_alloc(arrayP->len*(sizeof(psfont))); + if (!(FDArrayP)) return(SCAN_OUT_OF_MEMORY); + + /* get a specified number of font dictionaries */ + for (FDArrayIndex = 0; FDArrayIndex < arrayP->len; FDArrayIndex++) { + /* get "dup" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "dup", 3) != 0) + return(SCAN_ERROR); + /* get an integer digit */ + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) + return(SCAN_ERROR); + + /* read a CID version of a Type 1 font */ + if (!CIDType1fontfcnA(&rc)) + return(rc); + + /* get "put" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || strncmp(tokenStartP, "put", 3) != 0) + return(SCAN_ERROR); + } + return(SCAN_OK); +} +#endif + +static int +getArray(psobj *arrayP) +{ + int N; /* count the items in the array */ + psobj *objP; + + /* That is totally a kludge. If some stupid font file has + * /foo/foo # ftp://ftp.cdrom.com/pub/os2/fonts/future.zip + * we will treat it as /foo. + * H.J. */ + char tmp [1024]; + + strncpy (tmp, tokenStartP, sizeof (tmp)); + tmp [sizeof (tmp) - 1] = '\0'; + +restart: + scan_token(inputP); + switch (tokenType) + { + case TOKEN_LEFT_BRACE: + case TOKEN_LEFT_BRACKET: + break; + + case TOKEN_LITERAL_NAME: + tokenStartP[tokenLength] = '\0'; + if (strcmp (tokenStartP, tmp) == 0) + { + /* Ok, We see /foo/foo. Let's restart. */ + goto restart; + } + + default: + return(SCAN_ERROR); + } + /* format the array in memory, save pointer to the beginning */ + arrayP->data.valueP = tokenStartP; + /* loop, picking up next object, until right BRACE or BRACKET */ + N = 0; + do { + scan_token(inputP); + if ( (tokenType == TOKEN_RIGHT_BRACE) || + (tokenType == TOKEN_RIGHT_BRACKET) ) { + /* save then number of items in the array */ + arrayP->len = N; + return(SCAN_OK); + } + /* allocate the space for the object */ + objP = (psobj *)vm_alloc(sizeof(psobj)); + if (!(objP)) return(SCAN_OUT_OF_MEMORY); + + /* array is an array of numbers, (real or integer) */ + if (tokenType == TOKEN_REAL) { + objFormatReal(objP, tokenValue.real); + } + else + if (tokenType == TOKEN_INTEGER) { + objFormatInteger(objP, tokenValue.integer); + } + else return(SCAN_ERROR); + N++; + } while ( 1>0 ); + /* NOTREACHED*/ +} +/***================================================================***/ +static int +getName(char *nameP) +{ + do { + scan_token(inputP); + if (tokenType <= TOKEN_NONE) { + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(SCAN_ERROR); + } + } while ((tokenType != TOKEN_NAME) || + (0 != strncmp(tokenStartP,nameP,strlen(nameP))) ); + /* found */ + return(SCAN_OK); +} +/***================================================================***/ +static int +getNbytes(int N) +{ + int I; + + + tokenStartP = vm_next_byte(); + tokenMaxP = tokenStartP + MIN(vm_free_bytes(), MAX_STRING_LEN); + if (N > vm_free_bytes()) { + return(SCAN_OUT_OF_MEMORY); + } + I = T1Read(tokenStartP,1,N,inputP->data.fileP); + if ( I != N ) return(SCAN_FILE_EOF); + return(SCAN_OK); +} + +/***================================================================***/ +/* getLiteralName(nameObjP) */ +/* scan for next literal. */ +/* if we encounter the name 'end' then terminate and say ok. */ +/* It means that the CharStrings does not have as many characters */ +/* as the dictionary said it would and that is ok. */ +/***================================================================***/ +static int +getLiteralName(psobj *nameObjP) +{ + do { + scan_token(inputP); + if (tokenType <= TOKEN_NONE) { + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(SCAN_ERROR); + } + if (tokenType == TOKEN_NAME) { + if (0 == strncmp(tokenStartP,"end",3) ) { + return(SCAN_END); + } + } + } while (tokenType != TOKEN_LITERAL_NAME) ; + nameObjP->len = tokenLength; + /* allocate all the names in the CharStrings Structure */ + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + nameObjP->data.valueP = tokenStartP; + /* found */ + return(SCAN_OK); +} + +/***================================================================***/ +/* + * BuildSubrs routine + */ +/***================================================================***/ + +static int +BuildSubrs(psfont *FontP) +{ + int N; /* number of values in Subrs */ + int I; /* index into Subrs */ + int i; /* loop thru Subrs */ + int J; /* length of Subrs entry */ + psobj *arrayP; + + /* next token should be a positive int */ + /* note: rc is set by getInt. */ + N = getInt(); + if (rc) return(rc); + if (N < 0 ) return(SCAN_ERROR); + /* if we already have a Subrs, then skip the second one */ + /* The second one is for hiresolution devices. */ + if (FontP->Subrs.data.arrayP != NULL) { + TwoSubrs = TRUE; + /* process all the Subrs, but do not update anything */ + /* can not just skip them because of the binary data */ + for (i=0;i INT_MAX / sizeof(psobj)) + return (SCAN_ERROR); + arrayP = (psobj *)vm_alloc(N*sizeof(psobj)); + if (!(arrayP) ) return(SCAN_OUT_OF_MEMORY); + FontP->Subrs.len = N; + FontP->Subrs.data.arrayP = arrayP; + /* get N values for Subrs */ + for (i=0;i INT_MAX / sizeof(psdict)) return(SCAN_ERROR); + /* save number of entries in the dictionary */ + + dictP = (psdict *)vm_alloc((N+1)*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + FontP->CharStringsP = dictP; + dictP[0].key.len = N; + /* get N values for CharStrings */ + for (i=1;i<=N;i++) { + /* look for next literal name */ + rc = getLiteralName(&(dictP[i].key)); + if (rc) return(rc); + /* get 1 integer */ + J = getInt(); + if (rc) return(rc); /* if next token was not an Int */ + if (J<0) return (SCAN_ERROR); + dictP[i].value.len = J; + /* get the next token, it should be RD or -|, either is ok */ + rc = getNextValue(TOKEN_NAME); + if ( rc != SCAN_OK ) return(rc); + rc = getNbytes(J); + if (rc == SCAN_OK) { + dictP[i].value.data.valueP = tokenStartP; + if ( !(vm_alloc(J)) ) return(SCAN_OUT_OF_MEMORY); + } + else return(rc); + } + return(SCAN_OK); + +} +/***================================================================***/ +#if XFONT_CID +/***================================================================***/ +/* + * BuildCIDFontInfo Dictionary + */ +/***================================================================***/ +static int +BuildCIDFontInfo(cidfont *CIDfontP) +{ + psdict *dictP; + + /* allocate the private dictionary (max number of entries + 1) */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + CIDfontP->CIDfontInfoP = dictP; + CIDfontP->CIDfontInfoP[0].key.len = 18; /* number of actual entries */ + objFormatName(&(dictP[CIDCOUNT].key),8,"CIDCount"); + objFormatInteger(&(dictP[CIDCOUNT].value),-1); + objFormatName(&(dictP[CIDFONTNAME].key),11,"CIDFontName"); + objFormatName(&(dictP[CIDFONTNAME].value),0,NULL); + objFormatName(&(dictP[CIDFONTTYPE].key),11,"CIDFontType"); + objFormatInteger(&(dictP[CIDFONTTYPE].value),-1); + objFormatName(&(dictP[CIDVERSION].key),14,"CIDFontVersion"); + objFormatInteger(&(dictP[CIDVERSION].value),-1); + objFormatName(&(dictP[CIDREGISTRY].key),8,"Registry"); + objFormatString(&(dictP[CIDREGISTRY].value),0,NULL); + objFormatName(&(dictP[CIDORDERING].key),8,"Ordering"); + objFormatString(&(dictP[CIDORDERING].value),0,NULL); + objFormatName(&(dictP[CIDSUPPLEMENT].key),10,"Supplement"); + objFormatInteger(&(dictP[CIDSUPPLEMENT].value),-1); + objFormatName(&(dictP[CIDMAPOFFSET].key),12,"CIDMapOffset"); + objFormatInteger(&(dictP[CIDMAPOFFSET].value),-1); + objFormatName(&(dictP[CIDFDARRAY].key),7,"FDArray"); + objFormatArray(&(dictP[CIDFDARRAY].value),0,NULL); + objFormatName(&(dictP[CIDFDBYTES].key),7,"FDBytes"); + objFormatInteger(&(dictP[CIDFDBYTES].value),-1); + objFormatName(&(dictP[CIDFONTBBOX].key),8,"FontBBox"); + objFormatArray(&(dictP[CIDFONTBBOX].value),0,NULL); + objFormatName(&(dictP[CIDFULLNAME].key),8,"FullName"); + objFormatString(&(dictP[CIDFULLNAME].value),0,NULL); + objFormatName(&(dictP[CIDFAMILYNAME].key),10,"FamilyName"); + objFormatString(&(dictP[CIDFAMILYNAME].value),0,NULL); + objFormatName(&(dictP[CIDWEIGHT].key),6,"Weight"); + objFormatString(&(dictP[CIDWEIGHT].value),0,NULL); + objFormatName(&(dictP[CIDNOTICE].key),6,"Notice"); + objFormatString(&(dictP[CIDNOTICE].value),0,NULL); + objFormatName(&(dictP[CIDGDBYTES].key),7,"GDBytes"); + objFormatInteger(&(dictP[CIDGDBYTES].value),-1); + objFormatName(&(dictP[CIDUIDBASE].key),7,"UIDBase"); + objFormatInteger(&(dictP[CIDUIDBASE].value),0); + objFormatName(&(dictP[CIDXUID].key),4,"XUID"); + objFormatInteger(&(dictP[CIDXUID].value),0); + return(SCAN_OK); +} +/***================================================================***/ +/* + * BuildCMapInfo Dictionary + */ +/***================================================================***/ +static int +BuildCMapInfo(cmapres *CMapP) +{ + psdict *dictP; + + /* allocate the private dictionary (max number of entries + 1) */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + CMapP->CMapInfoP = dictP; + CMapP->CMapInfoP[0].key.len = 8; /* number of actual entries */ + objFormatName(&(dictP[CMAPREGISTRY].key),8,"Registry"); + objFormatString(&(dictP[CMAPREGISTRY].value),0,NULL); + objFormatName(&(dictP[CMAPORDERING].key),8,"Ordering"); + objFormatString(&(dictP[CMAPORDERING].value),0,NULL); + objFormatName(&(dictP[CMAPSUPPLEMENT].key),10,"Supplement"); + objFormatInteger(&(dictP[CMAPSUPPLEMENT].value),-1); + objFormatName(&(dictP[CMAPNAME].key),8,"CMapName"); + objFormatString(&(dictP[CMAPNAME].value),0,NULL); + objFormatName(&(dictP[CMAPVERSION].key),11,"CMapVersion"); + objFormatInteger(&(dictP[CMAPVERSION].value),-1); + objFormatName(&(dictP[CMAPTYPE].key),8,"CMapType"); + objFormatInteger(&(dictP[CMAPTYPE].value),-1); + objFormatName(&(dictP[CMAPWMODE].key),5,"WMode"); + objFormatInteger(&(dictP[CMAPWMODE].value),-1); + objFormatName(&(dictP[CMAPCIDCOUNT].key),8,"CIDCount"); + objFormatInteger(&(dictP[CMAPCIDCOUNT].value),-1); + return(SCAN_OK); +} +#endif + +/***================================================================***/ +/* + * BuildFontInfo Dictionary + */ +/***================================================================***/ +static int +BuildFontInfo(psfont *fontP) +{ + psdict *dictP; + + /* allocate the private dictionary */ + dictP = (psdict *)vm_alloc(20*sizeof(psdict)); + if (!(dictP)) return(SCAN_OUT_OF_MEMORY); + + fontP->fontInfoP = dictP; + fontP->fontInfoP[0].key.len = 17; /* number of actual entries */ + objFormatName(&(dictP[FONTNAME].key),8,"FontName"); + objFormatName(&(dictP[FONTNAME].value),0,NULL); + objFormatName(&(dictP[PAINTTYPE].key),9,"PaintType"); + objFormatInteger(&(dictP[PAINTTYPE].value),0); + objFormatName(&(dictP[FONTTYPENUM].key),8,"FontType"); + objFormatInteger(&(dictP[FONTTYPENUM].value),0); + objFormatName(&(dictP[FONTMATRIX].key),10,"FontMatrix"); + objFormatArray(&(dictP[FONTMATRIX].value),0,NULL); + objFormatName(&(dictP[FONTBBOX].key),8,"FontBBox"); + objFormatArray(&(dictP[FONTBBOX].value),0,NULL); + objFormatName(&(dictP[ENCODING].key),8,"Encoding"); + objFormatEncoding(&(dictP[ENCODING].value),0,NULL); + objFormatName(&(dictP[UNIQUEID].key),8,"UniqueID"); + objFormatInteger(&(dictP[UNIQUEID].value),0); + objFormatName(&(dictP[STROKEWIDTH].key),11,"StrokeWidth"); + objFormatReal(&(dictP[STROKEWIDTH].value),0.0); + objFormatName(&(dictP[VERSION].key),7,"version"); + objFormatString(&(dictP[VERSION].value),0,NULL); + objFormatName(&(dictP[NOTICE].key),6,"Notice"); + objFormatString(&(dictP[NOTICE].value),0,NULL); + objFormatName(&(dictP[FULLNAME].key),8,"FullName"); + objFormatString(&(dictP[FULLNAME].value),0,NULL); + objFormatName(&(dictP[FAMILYNAME].key),10,"FamilyName"); + objFormatString(&(dictP[FAMILYNAME].value),0,NULL); + objFormatName(&(dictP[WEIGHT].key),6,"Weight"); + objFormatString(&(dictP[WEIGHT].value),0,NULL); + objFormatName(&(dictP[ITALICANGLE].key),11,"ItalicAngle"); + objFormatReal(&(dictP[ITALICANGLE].value),0.0); + objFormatName(&(dictP[ISFIXEDPITCH].key),12,"isFixedPitch"); + objFormatBoolean(&(dictP[ISFIXEDPITCH].value),FALSE); + objFormatName(&(dictP[UNDERLINEPOSITION].key),17,"UnderlinePosition"); + objFormatReal(&(dictP[UNDERLINEPOSITION].value),0.0); + objFormatName(&(dictP[UNDERLINETHICKNESS].key),18,"UnderlineThickness"); + objFormatReal(&(dictP[UNDERLINETHICKNESS].value),0.0); + return(SCAN_OK); +} +#if XFONT_CID +/***================================================================***/ +/* + * BuildCIDType1Private Dictionary + */ +/***================================================================***/ +static int +BuildCIDType1Private(psfont *fontP) +{ + psdict *Private; + + /* allocate the private dictionary */ + Private = (psdict *)vm_alloc(21*sizeof(psdict)); + + if (!(Private)) return(SCAN_OUT_OF_MEMORY); + + fontP->Private = Private; + fontP->Private[0].key.len = 20; /* number of actual entries */ + + objFormatName(&(Private[CIDT1MINFEATURE].key),10,"MinFeature"); + objFormatArray(&(Private[CIDT1MINFEATURE].value),0,NULL); + objFormatName(&(Private[CIDT1LENIV].key),5,"lenIV"); + objFormatInteger(&(Private[CIDT1LENIV].value),DEFAULTLENIV); + objFormatName(&(Private[CIDT1LANGGROUP].key),13,"LanguageGroup"); + objFormatInteger(&(Private[CIDT1LANGGROUP].value),DEFAULTLANGUAGEGROUP); + objFormatName(&(Private[CIDT1BLUEVALUES].key),10,"BlueValues"); + objFormatArray(&(Private[CIDT1BLUEVALUES].value),0,NULL); + objFormatName(&(Private[CIDT1OTHERBLUES].key),10,"OtherBlues"); + objFormatArray(&(Private[CIDT1OTHERBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1BLUESCALE].key),9,"BlueScale"); + objFormatReal(&(Private[CIDT1BLUESCALE].value),DEFAULTBLUESCALE); + objFormatName(&(Private[CIDT1BLUEFUZZ].key),8,"BlueFuzz"); + objFormatInteger(&(Private[CIDT1BLUEFUZZ].value),DEFAULTBLUEFUZZ); + objFormatName(&(Private[CIDT1BLUESHIFT].key),9,"BlueShift"); + objFormatInteger(&(Private[CIDT1BLUESHIFT].value),DEFAULTBLUESHIFT); + objFormatName(&(Private[CIDT1FAMBLUES].key),11,"FamilyBlues"); + objFormatArray(&(Private[CIDT1FAMBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1FAMOTHERBLUES].key),16,"FamilyOtherBlues"); + objFormatArray(&(Private[CIDT1FAMOTHERBLUES].value),0,NULL); + objFormatName(&(Private[CIDT1STDHW].key),5,"StdHW"); + objFormatArray(&(Private[CIDT1STDHW].value),0,NULL); + objFormatName(&(Private[CIDT1STDVW].key),5,"StdVW"); + objFormatArray(&(Private[CIDT1STDVW].value),0,NULL); + objFormatName(&(Private[CIDT1STEMSNAPH].key),9,"StemSnapH"); + objFormatArray(&(Private[CIDT1STEMSNAPH].value),0,NULL); + objFormatName(&(Private[CIDT1STEMSNAPV].key),9,"StemSnapV"); + objFormatArray(&(Private[CIDT1STEMSNAPV].value),0,NULL); + /* skip password */ + objFormatName(&(Private[CIDT1SUBMAPOFF].key),13,"SubrMapOffset"); + objFormatInteger(&(Private[CIDT1SUBMAPOFF].value),0); + objFormatName(&(Private[CIDT1SDBYTES].key),7,"SDBytes"); + objFormatInteger(&(Private[CIDT1SDBYTES].value),0); + objFormatName(&(Private[CIDT1SUBRCNT].key),9,"SubrCount"); + objFormatInteger(&(Private[CIDT1SUBRCNT].value),0); + objFormatName(&(Private[CIDT1FORCEBOLD].key),9,"ForceBold"); + objFormatBoolean(&(Private[CIDT1FORCEBOLD].value),DEFAULTFORCEBOLD); + objFormatName(&(Private[CIDT1RNDSTEMUP].key),9,"RndStemUp"); + objFormatBoolean(&(Private[CIDT1RNDSTEMUP].value),DEFAULTRNDSTEMUP); + objFormatName(&(Private[CIDT1EXPFACTOR].key),15,"ExpansionFactor"); + objFormatReal(&(Private[CIDT1EXPFACTOR].value), + DEFAULTEXPANSIONFACTOR); + return(SCAN_OK); +} +#endif +/***================================================================***/ +/* + * BuildPrivate Dictionary + */ +/***================================================================***/ +static int +BuildPrivate(psfont *fontP) +{ + psdict *Private; + + /* allocate the private dictionary */ + Private = (psdict *)vm_alloc(20*sizeof(psdict)); + + if (!(Private)) return(SCAN_OUT_OF_MEMORY); + + fontP->Private = Private; + fontP->Private[0].key.len = 16; /* number of actual entries */ + + objFormatName(&(Private[BLUEVALUES].key),10,"BlueValues"); + objFormatArray(&(Private[BLUEVALUES].value),0,NULL); + objFormatName(&(Private[OTHERBLUES].key),10,"OtherBlues"); + objFormatArray(&(Private[OTHERBLUES].value),0,NULL); + objFormatName(&(Private[FAMILYBLUES].key),11,"FamilyBlues"); + objFormatArray(&(Private[FAMILYBLUES].value),0,NULL); + objFormatName(&(Private[FAMILYOTHERBLUES].key),16,"FamilyOtherBlues"); + objFormatArray(&(Private[FAMILYOTHERBLUES].value),0,NULL); + objFormatName(&(Private[BLUESCALE].key),9,"BlueScale"); + objFormatReal(&(Private[BLUESCALE].value),DEFAULTBLUESCALE); + objFormatName(&(Private[BLUESHIFT].key),9,"BlueShift"); + objFormatInteger(&(Private[BLUESHIFT].value),DEFAULTBLUESHIFT); + objFormatName(&(Private[BLUEFUZZ].key),8,"BlueFuzz"); + objFormatInteger(&(Private[BLUEFUZZ].value),DEFAULTBLUEFUZZ); + objFormatName(&(Private[STDHW].key),5,"StdHW"); + objFormatArray(&(Private[STDHW].value),0,NULL); + objFormatName(&(Private[STDVW].key),5,"StdVW"); + objFormatArray(&(Private[STDVW].value),0,NULL); + objFormatName(&(Private[STEMSNAPH].key),9,"StemSnapH"); + objFormatArray(&(Private[STEMSNAPH].value),0,NULL); + objFormatName(&(Private[STEMSNAPV].key),9,"StemSnapV"); + objFormatArray(&(Private[STEMSNAPV].value),0,NULL); + objFormatName(&(Private[FORCEBOLD].key),9,"ForceBold"); + objFormatBoolean(&(Private[FORCEBOLD].value),DEFAULTFORCEBOLD); + objFormatName(&(Private[LANGUAGEGROUP].key),13,"LanguageGroup"); + objFormatInteger(&(Private[LANGUAGEGROUP].value),DEFAULTLANGUAGEGROUP); + objFormatName(&(Private[LENIV].key),5,"lenIV"); + objFormatInteger(&(Private[LENIV].value),DEFAULTLENIV); + objFormatName(&(Private[RNDSTEMUP].key),9,"RndStemUp"); + objFormatBoolean(&(Private[RNDSTEMUP].value),DEFAULTRNDSTEMUP); + objFormatName(&(Private[EXPANSIONFACTOR].key),9,"ExpansionFactor"); + objFormatReal(&(Private[EXPANSIONFACTOR].value), + DEFAULTEXPANSIONFACTOR); + return(SCAN_OK); +} +/***================================================================***/ +/**********************************************************************/ +/* GetType1Blues(fontP) */ +/* */ +/* Routine to support font-level hints. */ +/* */ +/* Gets all the Blues information from the Private dictionary */ +/* for the font. */ +/* */ +/* */ +/**********************************************************************/ +static int +GetType1Blues(psfont *fontP) +{ + psdict *PrivateDictP; /* the Private dict relating to hints */ + struct blues_struct *blues; /* ptr for the blues struct we will allocate */ + int i; + psobj *HintEntryP; + + + + /* get the Private dictionary pointer */ + PrivateDictP = fontP->Private; + + /* allocate the memory for the blues structure */ + blues = (struct blues_struct *) vm_alloc(sizeof(struct blues_struct)); + + if (!blues) return(SCAN_OUT_OF_MEMORY); + + /* Make fontP's blues ptr point to this newly allocated structure. */ + fontP->BluesP = blues; + + /* fill in the BlueValues array */ + HintEntryP = &(PrivateDictP[BLUEVALUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numBlueValues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMBLUEVALUES) { + blues->numBlueValues = NUMBLUEVALUES; + } else + blues->numBlueValues = HintEntryP->len; + for (i = 0; i<= blues->numBlueValues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->BlueValues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->BlueValues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->BlueValues[i] = 0; + } + } + + /* fill in the OtherBlues array */ + HintEntryP = &(PrivateDictP[OTHERBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numOtherBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMOTHERBLUES) { + blues->numOtherBlues = NUMOTHERBLUES; + } else + blues->numOtherBlues = HintEntryP->len; + for (i = 0; i<= blues->numOtherBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->OtherBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->OtherBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->OtherBlues[i] = 0; + } + } + + /* fill in the FamilyBlues array */ + HintEntryP = &(PrivateDictP[FAMILYBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numFamilyBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMFAMILYBLUES) { + blues->numFamilyBlues = NUMFAMILYBLUES; + } else + blues->numFamilyBlues = HintEntryP->len; + for (i = 0; i<= blues->numFamilyBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->FamilyBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->FamilyBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->FamilyBlues[i] = 0; + } + } + + /* fill in the FamilyOtherBlues array */ + HintEntryP = &(PrivateDictP[FAMILYOTHERBLUES].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numFamilyOtherBlues = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMFAMILYOTHERBLUES) { + blues->numFamilyOtherBlues = NUMFAMILYOTHERBLUES; + } else + blues->numFamilyOtherBlues = HintEntryP->len; + for (i = 0; i<= blues->numFamilyOtherBlues-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->FamilyOtherBlues[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->FamilyOtherBlues[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->FamilyOtherBlues[i] = 0; + } + } + + /* fill in the StemSnapH array */ + HintEntryP = &(PrivateDictP[STEMSNAPH].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numStemSnapH = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMSTEMSNAPH) { + blues->numStemSnapH = NUMSTEMSNAPH; + } else + blues->numStemSnapH = HintEntryP->len; + for (i = 0; i<= blues->numStemSnapH-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->StemSnapH[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->StemSnapH[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->StemSnapH[i] = 0; + } + } + + /* fill in the StemSnapV array */ + HintEntryP = &(PrivateDictP[STEMSNAPV].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + blues->numStemSnapV = 0; + else { + /* get the number of values in the array */ + if (HintEntryP->len > NUMSTEMSNAPV) { + blues->numStemSnapV = NUMSTEMSNAPV; + } else + blues->numStemSnapV = HintEntryP->len; + for (i = 0; i<= blues->numStemSnapV-1; ++i) { + if (objPIsInteger(&HintEntryP->data.arrayP[i])) + blues->StemSnapV[i] = + HintEntryP->data.arrayP[i].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[i])) + blues->StemSnapV[i] = + HintEntryP->data.arrayP[i].data.real; + else + blues->StemSnapV[i] = 0; + } + } + + /* fill in the StdVW array */ + HintEntryP = &(PrivateDictP[STDVW].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + /* a value of zero signifies no entry */ + blues->StdVW = 0; + else { + if (HintEntryP->len > NUMSTDVW) { + } + if (objPIsInteger(&HintEntryP->data.arrayP[0])) + blues->StdVW = HintEntryP->data.arrayP[0].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[0])) + blues->StdVW = HintEntryP->data.arrayP[0].data.real; + else + blues->StdVW = 0; + } + + /* fill in the StdHW array */ + HintEntryP = &(PrivateDictP[STDHW].value); + /* check to see if the entry exists and if it's an array */ + if ( !objPIsArray(HintEntryP) || (HintEntryP->len == 0 )) + /* a value of zero signifies no entry */ + blues->StdHW = 0; + else { + if (HintEntryP->len > NUMSTDHW) { + } + if (objPIsInteger(&HintEntryP->data.arrayP[0])) + blues->StdHW = HintEntryP->data.arrayP[0].data.integer; + else if (objPIsReal(&HintEntryP->data.arrayP[0])) + blues->StdHW = HintEntryP->data.arrayP[0].data.real; + else + blues->StdHW = 0; + } + + + /* get the ptr to the BlueScale entry */ + HintEntryP = &(PrivateDictP[BLUESCALE].value); + /* put the BlueScale in the blues structure */ + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueScale = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueScale = HintEntryP->data.real; + else + blues->BlueScale = DEFAULTBLUESCALE; + + /* get the ptr to the BlueShift entry */ + HintEntryP = &(PrivateDictP[BLUESHIFT].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueShift = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueShift = HintEntryP->data.real; + else + blues->BlueShift = DEFAULTBLUESHIFT; + + /* get the ptr to the BlueFuzz entry */ + HintEntryP = &(PrivateDictP[BLUEFUZZ].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->BlueFuzz = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) /* Error? */ + blues->BlueFuzz = HintEntryP->data.real; + else + blues->BlueFuzz = DEFAULTBLUEFUZZ; + + /* get the ptr to the ForceBold entry */ + HintEntryP = &(PrivateDictP[FORCEBOLD].value); + if (objPIsBoolean(HintEntryP)) /* Must be integer! */ + blues->ForceBold = HintEntryP->data.boolean; + else + blues->ForceBold = DEFAULTFORCEBOLD; + + /* get the ptr to the LanguageGroup entry */ + HintEntryP = &(PrivateDictP[LANGUAGEGROUP].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->LanguageGroup = HintEntryP->data.integer; + else + blues->LanguageGroup = DEFAULTLANGUAGEGROUP; + + /* get the ptr to the RndStemUp entry */ + HintEntryP = &(PrivateDictP[RNDSTEMUP].value); + if (objPIsBoolean(HintEntryP)) /* Must be integer! */ + blues->RndStemUp = HintEntryP->data.boolean; + else + blues->RndStemUp = DEFAULTRNDSTEMUP; + + /* get the ptr to the lenIV entry */ + HintEntryP = &(PrivateDictP[LENIV].value); + if (objPIsInteger(HintEntryP)) /* Must be integer! */ + blues->lenIV = HintEntryP->data.integer; + else + blues->lenIV = DEFAULTLENIV; + + /* get the ptr to the ExpansionFactor entry */ + HintEntryP = &(PrivateDictP[EXPANSIONFACTOR].value); + if (objPIsInteger(HintEntryP)) + blues->ExpansionFactor = HintEntryP->data.integer; + else if (objPIsReal(HintEntryP)) + blues->ExpansionFactor = HintEntryP->data.real; + else + blues->ExpansionFactor = DEFAULTEXPANSIONFACTOR; + return(SCAN_OK); +} +/**********************************************************************/ +/* GetType1CharString(fontP,code) */ +/* */ +/* Look up code in the standard encoding vector and return */ +/* the charstring associated with the character name. */ +/* */ +/* fontP is the psfont structure. */ +/* */ +/* Returns a psobj (string) */ +/**********************************************************************/ +psobj * +GetType1CharString(psfont *fontP, unsigned char code) +{ + int N; /* the 'Nth' entry in the CharStrings */ + psobj *charnameP; /* points to psobj that is name of character*/ + + psdict *CharStringsDictP; /* dictionary with char strings */ + psobj *theStringP; /* the definition for the code */ + + + + if (StdEncArrayP == NULL) { + return(NULL); + } + /* use the code to index into the standard encoding vector */ + charnameP = &(StdEncArrayP[code]); + + /* test if the encoding array points to a name */ + if (!(objPIsName(charnameP)) ) { + return(NULL); + } + + /* Now that we have the character name out of the standardencoding */ + /* get the character definition out of the current font */ + CharStringsDictP = fontP->CharStringsP; + + /* search the chars string for this charname as key */ + N = SearchDictName(CharStringsDictP,charnameP); + if (N<=0) { + return(NULL); + } + /* OK, the nth item is the psobj that is the string for this char */ + theStringP = &(CharStringsDictP[N].value); + + return(theStringP); +} + +/***================================================================***/ +/* + * FindDictValue + */ +/***================================================================***/ + +static int +FindDictValue(psdict *dictP) +{ + psobj LitName; + int N; + int V; + + /* we have just scanned a token and it is a literal name */ + /* need to check if that name is in Private dictionary */ + objFormatName(&LitName,tokenLength,tokenStartP); + /* is it in the dictP */ + N = SearchDictName(dictP,&LitName); + /* if found */ + if ( N > 0 ) { + /* what type */ + switch (dictP[N].value.type) { + case OBJ_ENCODING: + V = getEncoding(&(dictP[N].value)); + if ( V != SCAN_OK ) return(V); + break; + case OBJ_ARRAY: +#if XFONT_CID + if (0 == strncmp(tokenStartP,"FDArray",7)) + V = getFDArray(&(dictP[N].value)); + else + V = getArray(&(dictP[N].value)); +#else + V = getArray(&(dictP[N].value)); +#endif + if ( V != SCAN_OK ) return(V); + break; + case OBJ_INTEGER: + /* next value in integer */ + dictP[N].value.data.integer = getInt(); + if (rc) return(rc); /* if next token was not an Int */ + break; + case OBJ_REAL: + /* next value must be real or int, store as a real */ + scan_token(inputP); + if (tokenType == TOKEN_REAL) { + dictP[N].value.data.real = tokenValue.real; + } + else + if (tokenType == TOKEN_INTEGER) { + dictP[N].value.data.real = tokenValue.integer; + } + else return(SCAN_ERROR); + break; + case OBJ_NAME: + V = getNextValue(TOKEN_LITERAL_NAME); + if ( V != SCAN_OK ) return(V); + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatName(&(dictP[N].value),tokenLength,tokenStartP); + break; + case OBJ_STRING: + V = getNextValue(TOKEN_STRING); + if ( V != SCAN_OK ) return(V); + if (!(vm_alloc(tokenLength)) ) return(SCAN_OUT_OF_MEMORY); + objFormatString(&(dictP[N].value),tokenLength,tokenStartP); + break; + case OBJ_BOOLEAN: + scan_token(inputP); + if (tokenType != TOKEN_NAME) { + return(SCAN_ERROR); + } + if (0 == strncmp(tokenStartP,"true",4) ) { + dictP[N].value.data.boolean =TRUE; + } + else + if (0 == strncmp(tokenStartP,"false",5) ) { + dictP[N].value.data.boolean =FALSE; + } + else return(SCAN_ERROR); + break; + + default: + return(SCAN_ERROR); + } + } + /* Name is not in dictionary. That is ok. */ + return(SCAN_OK); + +} +/***================================================================***/ + +#if XFONT_CID +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_cidfont(cidfont *CIDFontP, cmapres *CMapP) +{ + char filename[CID_PATH_MAX]; + char cmapfile[CID_PATH_MAX]; + char buf[CID_BUFSIZE]; + char filetype[3]; + FILE *fileP; + FILE *fileP1; + char *nameP; + int namelen; + int i, j; + int cread, rangecnt; + unsigned int char_row, char_col; + + filetype[0] = 'r'; + filetype[1] = 'b'; + filetype[2] = '\0'; + + /* copy the filename and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP= CIDFontP->CIDFontFileName.data.nameP; + namelen = CIDFontP->CIDFontFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(filename,nameP,namelen); + filename[namelen] = '\0'; + /* file name is now constructed */ + inputFile.data.fileP = NULL; + filterFile.data.fileP = NULL; + + /* check whether a CIDFont file */ + if ((fileP = fopen(filename,filetype))) { + cread = fread(buf, 1, CID_BUFSIZE, fileP); + fclose(fileP); + if (cread > 17) { + if (strncmp(buf, "%!", 2) || + strstr(buf, "Resource-CIDFont") == NULL) + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + + /* copy the CMap file name and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP = CMapP->CMapFileName.data.nameP; + namelen = CMapP->CMapFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(cmapfile,nameP,namelen); + cmapfile[namelen] = '\0'; + /* CMap file name is now constructed */ + inputFile1.data.fileP = NULL; + + /* check whether a CMap file */ + if ((fileP1 = fopen(cmapfile,filetype))) { + cread = fread(buf, 1, CID_BUFSIZE, fileP1); + fclose(fileP1); + if (cread > 17) { + if (strncmp(buf, "%!", 2) || + strstr(buf, "Resource-CMap") == NULL) + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + } else + return(SCAN_FILE_OPEN_ERROR); + + /* read the specified CMap file */ + inputP = &inputFile1; + + if (!(fileP1 = fopen(cmapfile,filetype))) + return(SCAN_FILE_OPEN_ERROR); + + objFormatFile(inputP,fileP1); + + if ((rc = BuildCMapInfo(CMapP)) != 0) + return(rc); + + /* Assume everything will be OK */ + rc = 0; + rangecnt = 0; + + do { + /* Scan the next token */ + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + rangecnt = tokenValue.integer; + + if (rangecnt < 0 || rangecnt > INT_MAX / sizeof(spacerangecode)) { + rc = SCAN_ERROR; + break; + } + /* ==> tokenLength, tokenTooLong, tokenType, and */ + /* tokenValue are now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + + rc = FindDictValue(CMapP->CMapInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"begincodespacerange",19)) { + CIDFontP->spacerangecnt++; + spacerangeP = (spacerange *)vm_alloc(sizeof(spacerange)); + if (!spacerangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + spacerangeP->next = NULL; + spacerangeP->rangecnt = rangecnt; + spacerangeP->spacecode = + (spacerangecode *)vm_alloc(rangecnt*sizeof(spacerangecode)); + if (!spacerangeP->spacecode) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + spacerangeP->spacecode[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + spacerangeP->spacecode[i].srcCodeLo += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + spacerangeP->spacecode[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + spacerangeP->spacecode[i].srcCodeHi += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + } + + if (CIDFontP->spacerangeP) { + if (CIDFontP->spacerangeP->next == NULL) + CIDFontP->spacerangeP->next = spacerangeP; + else { + spacerangeP->next = CIDFontP->spacerangeP->next; + CIDFontP->spacerangeP->next = spacerangeP; + } + } else + CIDFontP->spacerangeP = spacerangeP; + + /* read "endcodespacerange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endcodespacerange",17) != 0))) { + rc = SCAN_ERROR; + break; + } + } + if (0 == strncmp(tokenStartP,"begincidrange",13)) { + CIDFontP->cidrangecnt++; + cidrangeP = (cidrange *)vm_alloc(sizeof(cidrange)); + if (!cidrangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + cidrangeP->next = NULL; + cidrangeP->rangecnt = rangecnt; + cidrangeP->range = + (cidrangecode *)vm_alloc(rangecnt*sizeof(cidrangecode)); + if (!cidrangeP->range) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + cidrangeP->range[i].srcCodeLo += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + char_row = (cidrangeP->range[i].srcCodeLo >> 8) & 0xff; + char_col = cidrangeP->range[i].srcCodeLo & 0xff; + if (char_row < CMapP->firstRow) + CMapP->firstRow = char_row; + if (char_row > CMapP->lastRow) + CMapP->lastRow = char_row; + if (char_col < CMapP->firstCol) + CMapP->firstCol = char_col; + if (char_col > CMapP->lastCol) + CMapP->lastCol = char_col; + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + cidrangeP->range[i].srcCodeHi += + (unsigned char)tokenStartP[j] << (8 * (tokenLength - 1 - j)); + char_row = (cidrangeP->range[i].srcCodeHi >> 8) & 0xff; + char_col = cidrangeP->range[i].srcCodeHi & 0xff; + if (char_row < CMapP->firstRow) + CMapP->firstRow = char_row; + if (char_row > CMapP->lastRow) + CMapP->lastRow = char_row; + if (char_col < CMapP->firstCol) + CMapP->firstCol = char_col; + if (char_col > CMapP->lastCol) + CMapP->lastCol = char_col; + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + break; + } + cidrangeP->range[i].dstCIDLo = tokenValue.integer; + } + + if (CIDFontP->cidrangeP) { + if (CIDFontP->cidrangeP->next == NULL) + CIDFontP->cidrangeP->next = cidrangeP; + else { + cidrangeP->next = CIDFontP->cidrangeP->next; + CIDFontP->cidrangeP->next = cidrangeP; + } + } else + CIDFontP->cidrangeP = cidrangeP; + + /* read "endcidrange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endcidrange",11) != 0))) { + rc = SCAN_ERROR; + break; + } + } + + if (0 == strncmp(tokenStartP,"beginnotdefrange",16)) { + CIDFontP->notdefrangecnt++; + notdefrangeP = (cidrange *)vm_alloc(sizeof(cidrange)); + if (!notdefrangeP) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + notdefrangeP->next = 0; + notdefrangeP->rangecnt = rangecnt; + notdefrangeP->range = + (cidrangecode *)vm_alloc(rangecnt*sizeof(cidrangecode)); + if (!notdefrangeP->range) { + rc = SCAN_OUT_OF_MEMORY; + break; + } + for (i = 0; i < rangecnt; i++) { + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].srcCodeLo = 0; + for (j = 0; j < tokenLength; j++) + notdefrangeP->range[i].srcCodeLo = (int)(tokenStartP[j] << + (8 * (tokenLength - 1 - j))); + scan_token(inputP); + if (tokenType != TOKEN_HEX_STRING) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].srcCodeHi = 0; + for (j = 0; j < tokenLength; j++) + notdefrangeP->range[i].srcCodeHi = (int)(tokenStartP[j] << + (8 * (tokenLength - 1 - j))); + scan_token(inputP); + if (tokenType != TOKEN_INTEGER) { + rc = SCAN_ERROR; + break; + } + notdefrangeP->range[i].dstCIDLo = tokenValue.integer; + } + if (CIDFontP->notdefrangeP) { + if (CIDFontP->notdefrangeP->next == NULL) + CIDFontP->notdefrangeP->next = notdefrangeP; + else { + notdefrangeP->next = CIDFontP->notdefrangeP->next; + CIDFontP->notdefrangeP->next = notdefrangeP; + } + } else + CIDFontP->notdefrangeP = notdefrangeP; + + /* read "endnotdefrange" */ + scan_token(inputP); + if (tokenType != TOKEN_NAME || (tokenType == TOKEN_NAME && + (strncmp(tokenStartP,"endnotdefrange",14) != 0))) { + rc = SCAN_ERROR; + break; + } + } + + if (0 == strncmp(tokenStartP,"endcmap",7)) { + if (CMapP->CMapInfoP[CMAPREGISTRY].value.data.valueP == NULL || + CMapP->CMapInfoP[CMAPORDERING].value.data.valueP == NULL || + CMapP->CMapInfoP[CMAPSUPPLEMENT].value.data.integer == -1) { + rc = SCAN_ERROR; + break; + } else { + rc = SCAN_FILE_EOF; + break; + } + } + break; + } + } + while (rc == 0); + fclose(inputP->data.fileP); + if (tokenTooLong) + rc = SCAN_OUT_OF_MEMORY; + if (rc == SCAN_OUT_OF_MEMORY) return(rc); + + /* open the specified CIDFont file */ + if (!(fileP = fopen(filename,filetype))) + return(SCAN_FILE_OPEN_ERROR); + + inputP = &inputFile; + objFormatFile(inputP,fileP); + CIDWantFontInfo = TRUE; + TwoSubrs = FALSE; + rc = BuildCIDFontInfo(CIDFontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + + if (CIDWantFontInfo) { + rc = FindDictValue(CIDFontP->CIDfontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_STRING: + tokenStartP[tokenLength] = '\0'; + if (0 == strncmp(tokenStartP,"Binary",6)) { + CIDFontP->binarydata = 1; + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + CIDFontP->bytecnt = tokenValue.integer; + else { + rc = SCAN_ERROR; + break; + } + } else if (0 == strncmp(tokenStartP,"Hex",3)) { + /* not yet supported */ + rc = SCAN_ERROR; + break; +#if 0 + /* uncomment when the hex format is supported */ + CIDFontP->binarydata = 0; + scan_token(inputP); + if (tokenType == TOKEN_INTEGER) + CIDFontP->bytecnt = tokenValue.integer; + else { + rc = SCAN_ERROR; + break; + } +#endif + } + break; + case TOKEN_NAME: + /* end of PostScript and beginning of data */ + if (0 == strncmp(tokenStartP,"StartData",9)) { + /* every CIDFont must have an FDArray */ + /* check whether other required dictionary entries were found */ + if (CIDFontP->CIDfontInfoP[CIDFDARRAY].value.data.arrayP == NULL || + CIDFontP->CIDfontInfoP[CIDFONTNAME].value.data.nameP == NULL || + CIDFontP->CIDfontInfoP[CIDFONTTYPE].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDVERSION].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDREGISTRY].value.data.valueP == NULL || + CIDFontP->CIDfontInfoP[CIDORDERING].value.data.valueP == NULL || + CIDFontP->CIDfontInfoP[CIDSUPPLEMENT].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDFONTBBOX].value.data.arrayP == NULL || + CIDFontP->CIDfontInfoP[CIDMAPOFFSET].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDFDBYTES].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDGDBYTES].value.data.integer == -1 || + CIDFontP->CIDfontInfoP[CIDCOUNT].value.data.integer == -1) { + rc = SCAN_ERROR; + break; + } else { + /* do Registry and Ordering entries match? */ + if (strcmp(CIDFontP->CIDfontInfoP[CIDREGISTRY].value.data.valueP, + CMapP->CMapInfoP[CMAPREGISTRY].value.data.valueP) != 0 || + strcmp(CIDFontP->CIDfontInfoP[CIDORDERING].value.data.valueP, + CMapP->CMapInfoP[CMAPORDERING].value.data.valueP) != 0) { + rc = SCAN_ERROR; + break; + } else { + fclose(inputP->data.fileP); + return(SCAN_OK); + } + } + } + break; + } + + } + while (rc ==0); + fclose(inputP->data.fileP); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} + +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_cidtype1font(psfont *FontP) +{ + int i; + int begincnt = 0; /* counter for the number of unpaired begin operators */ + int currentfilefound = 0; + + WantFontInfo = TRUE; + InPrivateDict = FALSE; + TwoSubrs = FALSE; + rc = BuildFontInfo(FontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + filterFile.data.fileP = NULL; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + if (InPrivateDict ) { + rc = FindDictValue(FontP->Private); + /* we are not going to report errors */ + /* Sometimes the font file may test a value such as */ + /* testing to see if the font is alreadly loaded with */ + /* same UniqueID. We would faile on /UniqueID get */ + /* because we are expecting a int to follow UniqueID*/ + /* If the correct object type does not follow a Name*/ + /* then we will skip over it without reporting error except */ + /* out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } /* end of reading Private dictionary */ + else + if (0 == strncmp(tokenStartP,"Private",7) ) { + InPrivateDict = TRUE; + rc = BuildCIDType1Private(FontP); + break; + } + else + if (WantFontInfo) { + rc = FindDictValue(FontP->fontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"currentfile",11)) { + currentfilefound = 1; + break; + } else if (0 == strncmp(tokenStartP,"eexec",5)) { + if (currentfilefound == 1) { + currentfilefound = 0; + filterFile.data.fileP = CIDeexec(inputP->data.fileP); + if (filterFile.data.fileP == NULL) { + fclose(inputFile.data.fileP); + return(SCAN_FILE_OPEN_ERROR); + } + inputP = &filterFile; + } else { + rc = SCAN_ERROR; + break; + } + } else if (0 == strncmp(tokenStartP,"begin",5)) { + begincnt++; + currentfilefound = 0; + } else if (0 == strncmp(tokenStartP,"end",3)) { + currentfilefound = 0; + begincnt--; + if (begincnt == 0) { + if (filterFile.data.fileP != NULL) { + scan_token(inputP); /* get 'currentfile' */ + scan_token(inputP); /* get 'closefile' */ + inputP = &inputFile; + resetDecrypt(); + inputP->data.fileP->b_cnt = + F_BUFSIZ - (inputP->data.fileP->b_ptr - + inputP->data.fileP->b_base); + if (inputP->data.fileP->b_cnt > 0) { + for (i = 0; i < inputP->data.fileP->b_cnt; i++) + if (*(inputP->data.fileP->b_ptr + i) == '%') + break; + if (i < inputP->data.fileP->b_cnt) { + inputP->data.fileP->b_cnt -= i; + inputP->data.fileP->b_ptr += i; + } else + inputP->data.fileP->b_cnt = 0; + } + } + rc = SCAN_OK; + return(rc); + } + if (begincnt < 0) { + rc = SCAN_ERROR; + break; + } + } + break; + } + + } + while (rc == 0); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} +#endif + +/* + * ------------------------------------------------------------------- + * Scan the next token and convert it into an object + * Result is placed on the Operand Stack as next object + * ------------------------------------------------------------------- + */ +int +scan_font(psfont *FontP) +{ + + + char filename[128]; + char filetype[3]; + FILE *fileP; + char *nameP; + int namelen; + int V; + int i; + boolean starthex80; + + starthex80 = FALSE; + filetype[0] = 'r'; + filetype[1] = 'b'; + filetype[2] = '\0'; + /* copy the filename and remove leading or trailing blanks */ + /* point to name and search for leading blanks */ + nameP= FontP->FontFileName.data.nameP; + namelen = FontP->FontFileName.len; + while (nameP[0] == ' ') { + nameP++; + namelen--; + } + /* now remove any trailing blanks */ + while ((namelen>0) && ( nameP[namelen-1] == ' ')) { + namelen--; + } + strncpy(filename,nameP,namelen); + filename[namelen] = '\0'; + /* file name is now constructed */ + inputFile.data.fileP = NULL; + filterFile.data.fileP = NULL; + + inputP = &inputFile; + if ((fileP = T1Open(filename,filetype))) { + /* get the first byte of file */ + V = _XT1getc(fileP); + /* if file starts with x'80' then skip next 5 bytes */ + if ( V == 0X80 ) { + for (i=0;i<5;i++) V = _XT1getc(fileP); + starthex80 = TRUE; + } + else T1Ungetc(V,fileP); + objFormatFile(inputP,fileP); + } + else { + return(SCAN_FILE_OPEN_ERROR); + }; + + WantFontInfo = TRUE; + InPrivateDict = FALSE; + TwoSubrs = FALSE; + rc = BuildFontInfo(FontP); + if (rc != 0) return(rc); + + /* Assume everything will be OK */ + rc = 0; + + /* Loop until complete font is read */ + do { + /* Scan the next token */ + scan_token(inputP); + + /* ==> tokenLength, tokenTooLong, tokenType, and tokenValue are */ + /* now set */ + + switch (tokenType) { + case TOKEN_EOF: + case TOKEN_NONE: + case TOKEN_INVALID: + /* in this case we are done */ + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + rc = SCAN_ERROR; + break; + case TOKEN_LITERAL_NAME: + /* Look up the name */ + tokenStartP[tokenLength] = '\0'; + if (InPrivateDict ) { + if (0== strncmp(tokenStartP,"Subrs",5) ) { + rc = BuildSubrs(FontP); + break; + } + if (0== strncmp(tokenStartP,"CharStrings",11) ) { + rc = BuildCharStrings(FontP); + if ( (rc == SCAN_OK) ||(rc == SCAN_END) ) { + T1Close(inputP->data.fileP); + /* Build the Blues Structure */ + rc = GetType1Blues(FontP); + /* whatever the return code, return it */ + /* all the work is done. This is the normal exit.*/ + return(rc); + } + break; + } + rc = FindDictValue(FontP->Private); + /* we are not going to report errors */ + /* Sometimes the font file may test a value such as */ + /* testing to see if the font is alreadly loaded with */ + /* same UniqueID. We would faile on /UniqueID get */ + /* because we are expecting a int to follow UniqueID*/ + /* If the correct object type does not follow a Name*/ + /* then we will skip over it without reporting error except */ + /* when out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } /* end of reading Private dictionary */ + else + if (0== strncmp(tokenStartP,"Private",7) ) { + InPrivateDict = TRUE; + rc = BuildPrivate(FontP); + break; + } + else + if (WantFontInfo) { + rc = FindDictValue(FontP->fontInfoP); + /* we are not going to report errors except out of memory */ + if (rc != SCAN_OUT_OF_MEMORY) + rc = SCAN_OK; + break; + } + break; + case TOKEN_NAME: + if (0 == strncmp(tokenStartP,"eexec",5) ) { + /* if file started with x'80', check next 5 bytes */ + if (starthex80) { + V = _XT1getc(fileP); + if ( V == 0X80 ) { + for (i=0;i<5;i++) V = _XT1getc(fileP); + } + else T1Ungetc(V,fileP); + } + filterFile.data.fileP = T1eexec(inputP->data.fileP); + if (filterFile.data.fileP == NULL) { + T1Close(inputFile.data.fileP); + return(SCAN_FILE_OPEN_ERROR); + } + inputP = &filterFile; + + WantFontInfo = FALSE; + } + break; + } + + } + while (rc ==0); + T1Close(inputP->data.fileP); + if (tokenTooLong) return(SCAN_OUT_OF_MEMORY); + return(rc); +} + -- cgit v1.2.3