T168_111\appl\Text\Agfa:第129~133

sym.h  、、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/SYS/INC/SYM.H_V   1.30   Oct 04 2004 14:57:22   behringerk  $ */
/* $Log:   I:/BULL/URIP/SYS/INC/SYM.H_V  $ 
 * 
 *    Rev 1.30   Oct 04 2004 14:57:22   behringerk
 * added requirements field to SYMBOLSET structure
 * 
 *    Rev 1.29   Sep 02 2004 14:09:52   behringerk
 * fixed revision dates in code
 * 
 *    Rev 1.28   Sep 02 2004 13:50:40   behringerk
 * modified strucs to support character requirements field
 * 
 *    Rev 1.27   Aug 10 2004 12:26:20   galejss
 * changes for runtime no-symset-mappinng option
 * 
 *    Rev 1.26   Aug 22 2003 09:43:54   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.25   Jul 01 2003 18:03:26   Galejs
 * pss_directory[] only needed if symset mapping is enabled
 * 
 *    Rev 1.24   Sep 23 2002 14:27:38   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.23   Jul 26 2001 10:44:16   Galejs
 * remove unused SS_COUNT_TYPE and SS_COUNT_SIZE defines
 * 
 *    Rev 1.22   Feb 02 2000 11:34:00   galejs
 * changes to SYMBOLSET for simultaneous disk/rom
 * 
 *    Rev 1.21   Aug 09 1999 17:00:32   galejs
 * fix nested comments (compiler complaint)
 * 
 *    Rev 1.20   18 Feb 1999 21:29:34   DAVID
 * Changed CFFSID symbol to CFFCHARSET.
 * 
 *    Rev 1.19   25 Jan 1999 21:20:18   DAVID
 * Added defined symbol 'CFFSID' for CFF Charset Array access.
 * 
 *    Rev 1.18   20 Jan 1999 10:36:28   DAVID
 * Added defined symbol 'CFFENCODING', similar in use to
 * 'T1ENCODING'.
 * 
 *    Rev 1.17   31 Aug 1998 14:24:28   GALEJS
 * need to rename "class" to "sym_class" (C++ keyword conflict)
 * 
 *    Rev 1.16   12 Jun 1998 13:11:54   GALEJS
 * move all prototypes to shareinc.h
 * 
 *    Rev 1.15   18 Dec 1997 16:45:56   GALEJS
 * delete if-0 code
 * 
 *    Rev 1.14   02 Jan 1997 15:44:04   DAVID
 * Added tt_langID to SYMBOLSET structure to support GB and BIG5 Asian fonts.
 * 
 *    Rev 1.13   07 Apr 1995 11:31:20   LISA
 * Changed copyright information from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.12   19 Jan 1995 16:20:40   MARTIN
 * Added SYMmapTT.
 * 
 *    Rev 1.11   16 Jan 1995 14:14:52   JOE
 * Added support for MicroType symbol sets.
 * 
 *    Rev 1.10   16 Dec 1994 14:23:56   MARTIN
 * Added FCO_TT conditional around SYMmapReverse.
 * 
 *    Rev 1.9   15 Dec 1994 20:02:56   MARTIN
 * Added SYMmapReverse.
 * 
 *    Rev 1.8   08 Sep 1994 18:02:04   MIKE
 * #define SYMBOLSET_TT if FCO_RDR is enabled.
 * 
 *    Rev 1.7   08 Jun 1994 12:00:28   MIKE
 * Added prototype for SYMnoMap().
 * 
 *    Rev 1.6   22 Apr 1994 15:31:24   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.5   15 Jun 1993 11:14:22   ROB
 * Add 'T1ENCODING' to support type 1 encoding arrays.
 * 
 *    Rev 1.4   14 Jan 1993 11:14:20   LISA
 * Removed CntrlZ character
 * 
 *    Rev 1.3   15 Dec 1992 13:30:12   MIKE
 * No change.
 * 
 *    Rev 1.2   14 Dec 1992 08:47:54   LISA
 * No change.
 * 
 *    Rev 1.1   11 Dec 1992 15:05:12   LISA
 * Made change to keyword Log
 * 
 *    Rev 1.0   09 Dec 1992 11:38:30   LISA
 * Initial revision.
*/
/* $Date:   Oct 04 2004 14:57:22  $ */
/* sym.h */


/*--------------------------------*/
/* Symbol set file directoy entry */
/*--------------------------------*/

/*  Modification History:
 *
 *  24 Jun 91  ss   Changed PBYTE SYMBOLSET.pss_directory to PUBYTE.
 *  28 Jun 91  rs   Added prototype for SYMmapR().
 *  25 Oct 91  ss   Added SS_COUNT_SIZE and SS_COUNT_TYPE defines.
 *  28-Oct-91  jfd  Changed typedef for PSS_ENTRY from * to FARPTR * to get
 *                  rid of compiler warning when building medium model.
 *  02-Apr-92  rs   Portability cleanup (see port.h).
 *  08-Jul-92  jfd  Code cleanup.
 *  24-Sep-92  mby  Added UFSS_DIRECTORY structure; file IDs for UIF.SS and
 *                  UTT.SS file formats; #defined offsets into SS_DIR... and
 *                  UFSS_DIR... structures.
 *  29-Sep-92  mby  SYMBOLSET has pointers/handles to two symbol set directories.
 *                  Added GET_xWORD... GET_xLONG... macros.
 *  30-Sep-92  mby  Change SYMBOLSET.pss_entry declaration from PSS_ENTRY to
 *                  LPUW16. Change function declaration to SYMnew(UW16, UW16);
 *  30-Sep-92  jfd  Removed conditional compiles based on SPARC and
 *                  replaced with conditional compiles based on
 *                  (NAT_ALIGN == 4) wherever possible.
 *  08-Oct-92  mby  #defined SYMBOLSET_IF, SYMBOLSET_TT, NSS_FILES, whose
 *                  values depend on which FSTs are enabled. Changed SYMBOLSET
 *                  structure. Added SYMBOLSET.platID & SYMBOLSET.specID
 *  21-Oct-92  mby  Moved GET_x...() macros into "cgmacros.h"
 *  04-Jun-93  jfd  Added define for T1ENCODING (Type 1 Encoding).
 *  06-Jun-94  mby  Added prototype for SYMnoMap().
 *  08-Sep-94  mby  #define SYMBOLSET_TT if FCO_RDR is enabled.
 *  15-Dec-94  SBM  Added  SYMmapReverse.
 *  16-Dec-94  SBM  Added FCO_TT conditional around SYMmapReverse. Only the
 *                  TrueType generator uses this code for now.
 *  04-Jan-95  jfd  Added support for MicroType symbol sets.
 *  19-Jan-95  SBM  Added SYMmapTT.
 *  01-Jan-97  dlk  Added tt_langID to SYMBOLSET structure definition to make
 *                  it possible to distinguish between GB and BIG5 encoded fonts.
 *    12-Jun-98  slg    Move fn prototypes to shareinc.h
 *    31-Aug-98  slg    Need to rename "class" elements of SS_DIRECTORY and
 *                    UFSS_DIRECTORY to "sym_class" (avoid C++ keyword conflict) 
 * 20-Jan-99  dlk Added CFFENCODING symbol to function for CFF processing much
 *                as T1ENCODING functions for Type 1.
 * 25-Jan-99  dlk Added CFFSID symbol to function for CFF processing - chId
 *                values will be taken as CFF SIDs, and the Charset Array will
 *                be searched instead of the Encoding Array.
 * 18-Feb-99  dlk Changed CFFSID symbol to CFFCHARSET... same use and meaning.
 *  31-Jan-00  slg    Integrate disk/rom changes (for jd) - both "pss_directory"
 *                    and "hss_directory" can be in SYMBOLSET at the same time.
 */

#ifndef __SYM__
#define __SYM__

/*
CFF related items
*/

/*  This Symbol is defined with the same value as T1ENCODING, but     */
/*  no conflict should arise because a font cannot be CFF and regular */
/*  Type 1 at the same time.  The processing code paths are separate. */
/*                                                                    */
#define     CFFENCODING 0x8100   /* CFF Type2 Encoding */
#define     CFFCHARSET  0x8200   /* CFF SID values, and Charset Array */


/*
Type 1 related items
*/
#define     T1ENCODING  0x8100   /* Type 1 Encoding */


typedef struct
{
    UW16 ss_code;    /* symbol set code */
    UW16 symSetCode; /* 32 * PCLnum + (short)PCLchar - 64 */
    UW16 type;
    UW16 sym_class;
    UW16 first_code; /* first code */
    UW16 num_codes;  /* number of codes */
    UB8 requirements[8]; /* keb 9/02/04 */
    UL32 offset;     /* offset to symbol set in symbol set file */

}  SS_DIRECTORY;

typedef SS_DIRECTORY FARPTR * PSS_DIRECTORY;

typedef struct
{
    UW16 ss_code;    /* symbol set code */
    UW16 symSetCode; /* 32 * PCLnum + (short)PCLchar - 64 */
    UW16 type;
    UW16 sym_class;
    UW16 first_code; /* first code */
    UW16 num_codes;  /* number of codes */
    UB8 requirements[8]; /* keb 9/02/04 */
    UL32 offset;     /* offset to symbol set in symbol set file */
    UW16 platformID; /* Character mapping information required */
    UW16 specificID; /*   when loading TrueType fonts. */

}  UFSS_DIRECTORY;

typedef UFSS_DIRECTORY FARPTR * PUFSS_DIRECTORY;


#define IFSSIDN   0x55494631L   /* UIF.SS file identifier -- 9-24-92 */
#define TTSSIDN   0x55545431L   /* UTT.SS file identifier */
#define MTSSIDN   0x554D5431L   /* UMT.SS file identifier */

/* Offsets into SS_DIRECTORY and UFSS_DIRECTORY structures.    */
#define SSDIR_SIZE   24         /* keb 9/02/04 */
#define UFSSDIR_SIZE 28         /* keb 9/02/04 */
#define SSD_FILEID    0         /* 'UIF1', 'UTT1 or 'UMT1' */
#define SSD_NSS       4         /* Number of symbol sets */
#define SSD_DIRSIZE   6         /* sizeof(SS_DIRECTORY or UFSS_DIRECTORY) */
#define SSD_DOFF      8         /* Offset to start of directory table */
#define SSD_CODE      0         /* ss_code    */
#define SSD_SYMCODE   2         /* symSetCode */
#define SSD_TYPE      4         /* type       */
#define SSD_CLASS     6         /* class      */
#define SSD_FIRSTC    8         /* first code */
#define SSD_NUMC     10         /* num_codes  */
#define SSD_REQUIRE  12         /* requirements keb 9/02/04 */
#define SSD_OFF      20         /* offset     keb 9/02/04 */
#define SSD_PLID     24         /* platformID keb 9/02/04 */
#define SSD_SPID     26         /* specificID keb 9/02/04 */


/*--------------------------------*/
/*        Symbol set entry        */
/*--------------------------------*/

typedef struct
{
    UW16 cgnum;
    UW16 bucket_type;   /* no longer used */
} SS_ENTRY;
typedef SS_ENTRY FARPTR * PSS_ENTRY;

#if (IF_RDR || PST1_RDR)

#if FCO_RDR
#define  SYMBOLSET_IF  0
#define  SYMBOLSET_TT  1
#define  SYMBOLSET_MT  2
#define  NSS_FILES     3
#endif
#if (TT_RDR && !FCO_RDR)
#define  SYMBOLSET_IF  0
#define  SYMBOLSET_TT  1
#define  NSS_FILES     2
#endif
#if !(TT_RDR || FCO_RDR)
#define  SYMBOLSET_IF  0
#define  NSS_FILES     1
#endif

#else

#if FCO_RDR
#define  SYMBOLSET_TT  0
#define  SYMBOLSET_MT  1
#define  NSS_FILES     2
#endif
#if (TT_RDR && !FCO_RDR)
#define  SYMBOLSET_TT  0
#define  NSS_FILES     1
#endif

#endif


typedef struct
{
#if ROM
    LPUB8        pss_directory[NSS_FILES]; /* jwd, 11-8-99 */
#endif
#if DISK_FONTS
    MEM_HANDLE   hss_directory[NSS_FILES]; /* directory of symbol sets */
#endif
    LPUW16       pss_entry[NSS_FILES];     /* array of entries for cur IF ss */
    UW16         curssnum;                 /* current symbol set number     */
    UW16         ss_first_code[NSS_FILES]; /* current symbol set first code */
    UW16         ss_last_code[NSS_FILES];  /*  "        "     "  last code  */
    UW16         ss_symSetCode[NSS_FILES];
    UW16         ss_type[NSS_FILES];
    UW16         ss_class[NSS_FILES];
    UB8          ss_enabled[NSS_FILES];    /* 1 = YES; 0 = NO */
    UB8          ss_requirements[NSS_FILES][8]; /* keb 10/21/04 */
#if TT_RDR
    UW16         tt_platID;
    UW16         tt_specID;
    UW16         tt_langID;
#endif

} SYMBOLSET;


#endif    /* __SYM__ */
 

symmap.c   、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2005 Monotype Imaging Inc. All rights reserved.
 */

/* $Header:   I:/BULL/URIP/RTS/DA/SYMMAP.C_V   1.78   Dec 14 2004 14:17:48   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/DA/SYMMAP.C_V  $ 
 * 
 *    Rev 1.78   Dec 14 2004 14:17:48   galejss
 * make all DBG calls 16-bit-compatible
 * 
 *    Rev 1.77   Oct 04 2004 14:58:40   behringerk
 * added code to read in requirements field in sym sets from .ss files
 * 
 *    Rev 1.76   Oct 01 2004 11:50:06   galejss
 * if NO_SYMSET_MAPPING is enabled, don't treat missing .SS file as error
 * (assume that user will be using no-symset mapping exclusively)
 * 
 *    Rev 1.75   Aug 10 2004 15:23:50   galejss
 * changes for runtime no-symset-mapping option
 * 
 *    Rev 1.74   Jul 16 2004 16:45:24   galejss
 * USE_PS_ARRAY test
 * 
 *    Rev 1.73   Apr 27 2004 11:41:28   GalejsS
 * include unistd.h to fix compiler issue
 * 
 *    Rev 1.72   Sep 25 2003 13:47:32   Joe
 * Replaced "memcpy" with "MEMCPY".
 * 
 *    Rev 1.71   Aug 22 2003 08:53:42   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.70   Jul 21 2003 18:45:36   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.69   Jun 19 2003 18:49:44   Galejs
 * ufstport.h
 * 
 *    Rev 1.68   Oct 21 2002 18:12:18   Galejs
 * fix uninitialized-vbl warnings
 * 
 *    Rev 1.67   Sep 24 2002 11:47:34   Doolittl
 * Disable the swap in SYMnew() for PCLEOs; required as part of the CGIFfont_purge() issue.
 * 
 *    Rev 1.66   Mar 28 2002 14:36:50   Joe
 * Format 11 changes:
 * 1.) In SYMnew(), if unbound pcleo, do not
 * undo swapping of ssnum.
 * 
 *    Rev 1.65   May 03 2001 19:54:46   Galejs
 * data-type cleanup
 * 
 *    Rev 1.64   Dec 04 2000 15:54:44   Galejs
 * use new is_it_Asian() macro rather than explicit Asian-symbolset tests
 * 
 *    Rev 1.63   Nov 28 2000 18:54:44   Galejs
 * remove code for obsolete options PST1, FCO_TT
 * 
 *    Rev 1.62   Feb 02 2000 13:07:16   galejs
 * simult. disk/ROM changes (for clarity only)
 * 
 *    Rev 1.61   Jan 28 2000 15:25:14   galejs
 * use PATHNAMELEN (from port.h) rather than MAXNAME for buffersize
 * 
 *    Rev 1.60   Dec 10 1999 15:57:40   galejs
 * get rid of TT_ROM1 code
 * 
 *    Rev 1.59   Aug 17 1999 18:08:22   galejs
 * tr1_FirstLast() needs reentrancy parameter
 * 
 *    Rev 1.58   Aug 16 1999 13:10:28   galejs
 * include-file changes; USING_16_BIT_DOS test
 * 
 *    Rev 1.57   29 Jul 1999 17:08:26   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.56   26 Feb 1999 13:17:32   JOE
 * In SYMinit_ReadDir() and SYMnew(), initialized 'pathname' to 
 * NULL string (by aof).
 * 
 *    Rev 1.55   18 Feb 1999 21:36:16   DAVID
 * Changed CFFSID to CFFCHARSET.
 * 
 *    Rev 1.54   18 Feb 1999 18:10:48   DAVID
 * Uncoupled CFF processing from USE_UFST_MAPPING.
 * 
 *    Rev 1.53   26 Jan 1999 09:24:02   DAVID
 * Added checks for CFFENCODING and CFFSID - similar to
 * check for T1ENCODING.
 * 
 *    Rev 1.52   21 Jan 1999 13:58:44   GALEJS
 * standardize #include tests
 * 
 *    Rev 1.51   12 Jan 1999 17:15:54   GALEJS
 * use CONST for read-only data; move EXTERN dcls
 * 
 *    Rev 1.50   09 Dec 1998 08:29:48   JOE
 * Simplified internals of SYMnoMap() for setting 'q' data item based on
 * FSTs enabled and selected. Added support for FCO_RDR. (by jwd)
 * 
 *    Rev 1.49   15 Oct 1998 15:28:34   JOE
 * Changed conditional compile of SYMnoMap() (by ks).
 * 
 *    Rev 1.48   22 Jun 1998 17:43:56   GALEJS
 * pcleo.h in shareinc.h now
 * 
 *    Rev 1.47   15 Jun 1998 15:47:04   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.46   15 Apr 1998 17:42:26   GALEJS
 * move GLOBALs symbolset, symbolset_IF/TT/MT into IF_STATE
 * 
 *    Rev 1.45   02 Apr 1998 18:41:20   GALEJS
 * move extern to if_state
 * 
 *    Rev 1.44   30 Mar 1998 12:58:16   GALEJS
 * move short_path[], symbol_set[] into IF_STATE
 * 
 *    Rev 1.43   26 Mar 1998 16:54:38   GALEJS
 * kanji.h now in shareinc.h
 * 
 *    Rev 1.42   24 Mar 1998 15:53:44   GALEJS
 * include-file changes
 * 
 *    Rev 1.41   20 Mar 1998 12:10:50   GALEJS
 * 64-bit port
 * 
 *    Rev 1.40   18 Dec 1997 18:34:24   GALEJS
 * delete if-0 code
 * 
 *    Rev 1.39   23 Jun 1997 12:29:22   MIKE
 * Fix mistyping: pathTT => pathMT
 * 
 *    Rev 1.38   18 Jun 1997 18:39:48   GALEJS
 * filename kluge for PTV_OS port
 * 
 *    Rev 1.37   04 Jun 1997 16:35:58   DAVID
 * Added support for WANSUNG and JOHAB Korean encodings.
 * 
 *    Rev 1.36   22 Apr 1996 17:23:30   MIKE
 * OS9 support.
 * 
 *    Rev 1.35   01 Dec 1995 17:59:38   MIKE
 * Remove compiler warnings: <string.h>, unused arg in SYMmapTT()
 * 
 *    Rev 1.34   01 Dec 1995 14:53:28   MERRILL
 * quiet compler about fstType.
 * 
 *    Rev 1.33   18 Apr 1995 16:51:44   JOE
 * Changes to support the removal of symbol set mapping.
 * 
 *    Rev 1.32   06 Apr 1995 15:14:50   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.31   19 Jan 1995 16:20:16   MARTIN
 * Added SYMmapTT.
 * 
 *    Rev 1.30   16 Jan 1995 14:13:42   JOE
 * Added support for MicroType symbol sets.
 * 
 *    Rev 1.29   16 Dec 1994 14:23:24   MARTIN
 * Added FCO_TT conditional around SYMmapReverse.
 * 
 *    Rev 1.28   15 Dec 1994 20:02:32   MARTIN
 * Added SYMmapReverse.
 * 
 *    Rev 1.27   02 Dec 1994 21:25:38   MIKE
 * KSC (YAN).
 * 
 *    Rev 1.26   08 Sep 1994 19:06:54   MIKE
 * Use symbol_setTT and SYMBOLSET_TT for either FCO or TT.
 * 
 *    Rev 1.25   03 Aug 1994 19:46:26   MIKE
 * Added FCO changes from 1.18.1.1
 * 
 *    Rev 1.24   13 Jun 1994 12:55:36   MIKE
 * Made some code in SYMnoMap() conditional on PCLEO_RDR.
 * 
 *    Rev 1.23   08 Jun 1994 12:05:40   MIKE
 * Added SYMnoMap() to take care of downloaded symbol sets.
 * 
 *    Rev 1.22   22 Apr 1994 15:50:38   JOE
 * Changed conditional compile statement prior to including <hif.h>
 * to #if (_AM29K && !UNIX) to resolve UNIX Metaware compiler error.
 * 
 *    Rev 1.21   22 Apr 1994 13:55:06   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.20   09 Feb 1994 12:02:42   JOE
 * More _AM29K changes.
 * 
 *    Rev 1.19   02 Feb 1994 10:14:10   JOE
 * AM29K changes.
 * 
 *    Rev 1.18   05 Jan 1994 18:12:30   ROB
 * Add support for "GB" encoding.
 * 
 *    Rev 1.17   08 Dec 1993 18:59:12   ROB
 * General cleanup for MSDOS, FLAT, OS2.
 * 
 *    Rev 1.16   01 Dec 1993 08:40:52   JOE
 * Changed KANJI_ENCODING to ASIAN_ENCODING.
 * 
 *    Rev 1.15   30 Nov 1993 14:48:36   ROB
 * Add BIG5 support and TCA hooks.
 * 
 *    Rev 1.14   11 Nov 1993 16:30:04   JOE
 * In SYMnew(), added UNICODE changes for KANJI support.
 * 
 *    Rev 1.13   17 Aug 1993 14:50:06   JOE
 * In !ROM version of SYMinit(), corrected syntax error - changed line
 * "#ifdef DEBUG && !ROM" to #ifdef DEBUG".
 * 
 *    Rev 1.12   13 Aug 1993 14:53:54   MIKE
 * In SYMinit(), fix DEBUG compilation error.
 * 
 *    Rev 1.11   27 Jul 1993 11:41:50   JOE
 * Removed external declaration for "fontcontext".
 * In SYMnew(), replaced call to macro FC_ISEXTERN with in-line code
 * so as not to require "fontcontext" to be declared in this module.
 * 
 *    Rev 1.10   01 Jul 1993 15:15:12   JOE
 * EUC KANJI support.
 * 
 *    Rev 1.9   15 Jun 1993 10:39:46   JOE
 * Moved "vxWorks.h" before "port.h" to resolve conflicts.
 * 
 *    Rev 1.8   14 Jun 1993 17:18:34   ROB
 * Type 1 encoding array support.
 * 
 *    Rev 1.7   29 Mar 1993 10:55:46   ROB
 * Kanji cleanup.
 * 
 *    Rev 1.6   11 Mar 1993 15:07:28   MAIB
 * Initial changes to support Asian character encoding (TrueType 1st pass)
 * 
 *    Rev 1.5   15 Feb 1993 09:10:24   JOE
 * Changed all occurrences of READ to READF due to conflict with VXWorks.
 * 
 *    Rev 1.4   12 Feb 1993 13:31:32   JOE
 * VXWorks support.
 * 
 *    Rev 1.3   06 Jan 1993 15:46:34   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.2   14 Dec 1992 15:56:26   LISA
 * No change.
 * 
 *    Rev 1.1   14 Dec 1992 08:51:06   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 15:38:18   LISA
 * Initial revision.
*/
/* $Date:   Dec 14 2004 14:17:48  $ */
/* symmap.c */
/*
 *
 *
 * History
 *
 *   4-Feb-91  awr  Split off from ix.c.
 *                  Renamed init_symbol_set() to SYMinit() for new module.
 *                  Changed symbol set mapping to use SYMmap()
 *   5-Feb-91  jfd  In ROM version of SYMinit(), always return SUCCESS
 *                  or else return value is ambiguous.
 *  20 May 91  ss   Updated references to FMalloc_rd() & FMseek_rd() to
 *                  deleted last 2 parameters no longer needed.  Cleaned up
 *                  defines for these no longer used.
 *  17-Jun-91  jfd  Moved "debug.h" after "port.h".
 *                  Moved "cgconfig.h" before "port.h".
 *  24 Jun 91  ss   Conditionally compile io.h based on system type.
 *  27-Jun-91  rs   Add 'SYMmapR()' for reverse lookup of cgnum to chId.
 *  22-Aug-91  jfd  Conditionally compile SYMmapR based on PST1.
 *  25 Oct 91  ss   Added use of SS_COUNT_SIZE and SS_COUNT_TYPE to help 
 *                  with SPARC port.
 *  22 Nov 91  ss   Changed call to FMalloc_rd() in SYMinit() to use define
 *                  SS_COUNT_SIZE set in sym.h based on -DSPARC.
 *  03-Apr-92  rs   Portability cleanup (see port.h).
 *  08-Jul-92  rs   Code cleanup.
 *  10-Aug-92  rs   Change args in FMseek_read() from SW16 to int,
 *                  SL32 to long for 32 bit systems (Watcom C386).
 *  29-Sep-92  mby  Use GET_xWORD() and GET_xLONG() macros to extract 2- and
 *                  4-byte data from file (byte order is *always* HI-LO).
 *                  In SYMnew(), dumping file data into a structure pointer
 *                  is unsafe practice. Use GET_... macros to read data.
 *  30-Sep-92  mby  Call new function SYMinit_ReadDir(), from SYMinit().
 *                  SYMinit_ReadDir(fst_type) loads symbol set file
 *                  differently depending if fst_type is TrueType or not.
 *                  In SYMmap() symbolset.pss_entry is now a UW16 array. Ditto for SYMmapR().
 *                  SYMexit() frees symbolset.hufss_directory.
 *                  SYMnew() takes fst type as 2nd argument.
 *  08-Oct-92  mby  symbol_setIF[256] and symbol_setTT[256] so SYMnew() can
 *                  load both kinds of symbol sets. SYMBOLSET structure
 *                  (sym.h) was modified ==> changes to SYMmap(), SYMinit(),
 *                  SYMexit(), SYMnew(), SYMmapR().
 *  09-Oct-92  mby  SYMnew() returns error if can't load SS for req'd FST.
 *  20-Oct-92  jfd  In SYMinit(), corrected syntax error in "for" statement
 *                  ("," instead of ";"). Disabled code which references
 *                  "symbolset.hufss_directory". (No such structure member). 
 *  21-Oct-92  mby  Fixed bug in SYMnew() - returned bogus error.
 *                  #include "cgmacros.h" for GET_x...() macros.
 *  26-Oct-92  jfd  In SYMnew(), if processing a pcleo, do not swap bytes
 *                  when retrieving new symbol set number "new_ss_num".
 *                  Declared "fontcontext" as EXTERNAL.
 *  29-Oct-92  jfd  Moved declaration of "fontcontext" to outside "#if !ROM"
 *                  block.
 *                  Moved function prototype for SYMinit_ReadDir() to within
 *                  "#if !ROM" block to remove compiler warning.
 *  02-Nov-92  jfd  In SYMnew(), conditionally compiled code which checks 
 *                  the type of symbol set (IF or TT).
 *  15-Nov-92  rs   Port to Mac -> move "cgconfig.h" & "port.h" to start of
 *                  includes, include <unix.h>.
 *  23-Nov-92  mby  Clean up TT-only, IF-only code in SYMnew()
 *  06-Jan-93  jfd  ANSI C function declaration changes.
 *  08-Feb-93  jfd  VXWorks support.
 *  15-Feb-93  jfd  Changed READ to READF due to conflict with VXWorks.
 *  11-Mar-93  maib added code to begin to support JIS and SHIFT_JIS
 *                  character encoding
 *  27-Mar-93  rs   Add defines for KANJI_ENCODING, JIS_ENCODING &
 *                  SJIS_ENCODING per cgconfig.h.
 *  04-Jun-93  jfd  Add defines for USE_UFST_MAPPING per cgconfig.h.
 *  15-Jun-93  jfd  Moved "vxWorks.h" before "port.h" to resolve conflicts.
 *  30-Jun93 jfd/gy EUC KANJI support.
 *  27-Jul-93  jfd  Removed external declaration for "fontcontext".
 *                  In SYMnew(), replaced call to macro FC_ISEXTERN with
 *                  in-line code so as not to require "fontcontext" in
 *                  this module.
 *  12-Aug-93  mby  In SYMinit() fix DEBUG code - make symbolset.hss_directory
 *                  an array (see Oct '92 changes).
 *  17-Aug-93  jfd  In !ROM version of SYMinit(), corrected syntax error
 *                  - changed line "ifdef DEBUG && !ROM" to "#ifdef DEBUG".
 *  11-Nov-93  gy   In SYMnew(), added UNICODE changes for KANJI support.
 *  23-Nov-93  rs   Add BIG5 & TCA to KANJI_ENCODING support.
 *  01-Dec-93 jfd   Changed KANJI_ENCODING to ASIAN_ENCODING.
 *  08-Dec-93 rs    General cleanup - MSDOS & CGFLAT32.
 *  05-Jan-94 rs    Add support for "GB" encoding.
 *  27-Jan-94 jfd   Conditionally compiled #include for fcntl.h based
 *                  on (!defined(_AM29K) || (defined(_AM29K) && 
 *                  !defined(UNIX))).
 *  09-Feb-94 jfd   Including "hif.h" if _AM29K.
 *  22-Apr-94 jfd   Changed conditional compile statement prior to
 *                  including <hif.h> to #if (_AM29K && !UNIX) to
 *                  resolve UNIX Metaware compiler error.
 *  06-Jun-94 mby  Added SYMnoMap() to take care of downloaded symbol sets.
 *  13-Jun-94 mby  Made block of code in SYMnoMap() conditional on PCLEO_RDR.
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * FCO Changes from 1.18.1.1:
 *  15-Mar-94 mby  Added SYMmap() support for FCO_RDR for Unicode mapping.
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *  08-Sep-94 mby  symbol_setTT/SYMBOLSET_TT must be used for FCO font types
 *                 as well as TrueType.
 *  15-Dec-94 SBM  Added  SYMmapReverse.
 *  16-Dec-94 SBM  Added FCO_TT conditional around SYMmapReverse. Only the
 *                 TrueType generator uses this code for now.
 *  05-Jan-95 jfd  Added support for MicroType symbol sets.
 *  19-Jan-95 SBM  Added SYMmapTT.
 *  18-Apr-95 jfd  In SYMnoMap(), added support for the removal of symbol
 *                 set mapping.
 *                 Changed GET_WORD macro to version used in CGIF.C .
 *                 Conditifonally compiled SYMinit(), SYMexit(), SYMnew(),
 *                 SYMmap() and SYMmapR() based on NO_SYMSET_MAPPING.
 *  01-Dec-95 mby  Added <string.h>. Fixed compiler warning in SYMmapTT().
 *  22-Apr-96 mby  Conditionalize <fcntl.h> for OS9 port.
 *  22-May-97 dlk  Added WANSUNG and JOHAB to ASIAN_ENCODING test in SYMnew().
 *  18-Jun-97 slg  Allow PTV_OS compilation
 *  23-Jun-97 mby  Fix mistyping: pathTT -> pathMT
 *    09-Mar-98 slg  Don't use "long" dcls (incorrect if 64-bit platform)
 *    30-Mar-98 slg  MLOCAL short_path[] becomes if_state.short_path[];
 *                   MLOCAL symbol_set[] becomes if_state.symbol_set_symm[].
 *    15-Apr-98 slg  Move GLOBALs symbolset, symbol_setIF[], symbol_setTT[],
 *                   symbol_setMT[] to IF_STATE.
 * 15-Oct-98 ks   Conditionally compile SYMnoMap for ((PCLEO_RDR || TT_ROM1) && NO_SYMSET_MAPPING) to
 *                      fix compile bug \rts\da\symmap.c error SYMBOLSET_IF undeclared ident. when FCO_DISK is enabled.
 * 08-Dec-98 jwd  Simplified internals of SYMnoMap() for setting of 'q' data item
 *                based on FSTs enabled and selected; added support for FCO_RDR. Restored
 *                conditional compile requirements to previous.
 * 26-Jan-99 dlk  Added checks for CFFENCODING and CFFSID - similiar to
 *                check for T1ENCODING.
 * 18-Feb-99 dlk  Uncoupled checks for CFFENCODING and CFFSID from USE_UFST_MAPPING.
 * 18-Feb-99 dlk  Changed CFFSID to CFFCHARSET.
 * 26-Feb-99 aof  In SYMinit_ReadDir() and SYMnew(), initialized "pathname"
 *                array to null string.
 * 28-July-99 ks  Changed DEBUG compiler directive to AGFADEBUG.
 * 28-Jan-00 slg  Use PATHNAMELEN (from port.h) rather than locally-defined (and
 *                  incorrect) MAXNAME; replace some !ROM tests by DISK_FONTS. 
 * 28-Mar-02 jfd  In SYMnew(), if unbound pcleo, do not undo swapping of ssnum.
 * 25-Sep-03 jfd  Replaced "memcpy" with "MEMCPY".
 *
 */


#include "cgconfig.h"

#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include "ufstport.h"

#include <stdio.h>

#if MAYBE_FCNTL_H
#include <fcntl.h>
#endif

#if MAYBE_FCNTL_HIF_H
#include <fcntl.h>
#include <hif.h>  /* 2-7-94 jfd */
#endif

#if MAYBE_UNISTD_H
#include <unistd.h>
#endif

#include <string.h>  /* declaration for memcpy function */

#if MAYBE_IO_H
#include <io.h>
#endif

#include "dbg_ufst.h"

#include "shareinc.h"

#include "mixmodel.h"
#include "cgmacros.h"


/* Symbol sets */

#if DISK_FONTS
#if (IF_RDR  ||  PST1_RDR)
CONST LPSB8       pathIF = "uif.ss";
#endif

#if (TT_RDR || FCO_RDR)
CONST LPSB8       pathTT = "utt.ss";
#endif

#if FCO_RDR
CONST LPSB8       pathMT = "umt.ss";
#endif

#ifdef LINT_ARGS
MLOCAL UW16        SYMinit_ReadDir(FSP SL32);
#else
MLOCAL UW16        SYMinit_ReadDir();
#endif
#endif    /* DISK_FONTS */

/*------------------*/
/*     SYMmap       */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  SYMmap (FSP SW16 chId, SL32 fst_type)
#else
GLOBAL UW16
SYMmap (chId, fst_type)
    SW16 chId;
    SL32  fst_type;
#endif
{
    register LPUB8  ptr;

#if ((IF_RDR || PST1_RDR)  &&  (TT_RDR || FCO_RDR))
/* Remember that data in pss_entry arrays is in Hi-Lo byte order!! */

    if (fst_type != FC_TT_TYPE
#if FCO_RDR
           && fst_type != FC_FCO_TYPE
#endif
       )
        {
        if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_IF]) ||
              (if_state.symbolset.ss_last_code[SYMBOLSET_IF] < chId))
            return 0;
        ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_IF] +
                       (chId - if_state.symbolset.ss_first_code[SYMBOLSET_IF]) );
        return (GET_xWORD(ptr));
        }
    else
        {
#if FCO_RDR

           /* If IF font in MicroType, 
            * use MicroType symbolset for mapping.
            */

           if (fst_type == FC_FCO_TYPE && 
               if_state.pbucket->p.fco.design_EmRes == 8782) /* map to MT ss */
           {
              if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_MT]) ||
                     (if_state.symbolset.ss_last_code[SYMBOLSET_MT] < chId))
                  return 0;
              ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_MT] +
                       (chId - if_state.symbolset.ss_first_code[SYMBOLSET_MT]) );
              return (GET_xWORD(ptr));
           }
           else
#endif
           {
              if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_TT]) ||
                     (if_state.symbolset.ss_last_code[SYMBOLSET_TT] < chId))
                  return 0;
              ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_TT] +
                       (chId - if_state.symbolset.ss_first_code[SYMBOLSET_TT]) );
              return (GET_xWORD(ptr));
           }
        }

#else   /* either (IF_RDR || PST1_RDR) or (TT_RDR || FCO_RDR) but not both. */

#if (IF_RDR  ||  PST1_RDR)
    if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_IF]) ||
          (if_state.symbolset.ss_last_code[SYMBOLSET_IF] < chId))
        return 0;
    ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_IF] +
                   (chId - if_state.symbolset.ss_first_code[SYMBOLSET_IF]) );
    return (GET_xWORD(ptr));
#endif

#if FCO_RDR

           /* If IF font in MIcroType, 
            * use MicroType symbolset for mapping.
            */

DBG2("fst_type:%d, if_state.pbucket->p.fco.design_EmRes:%d\r\n",fst_type, if_state.pbucket->p.fco.design_EmRes);
DBG3("chId:%d,first:%d,last:%d\r\n", chId,if_state.symbolset.ss_first_code[SYMBOLSET_MT],
                                          if_state.symbolset.ss_last_code[SYMBOLSET_MT]);
    if (fst_type == FC_FCO_TYPE &&
        if_state.pbucket->p.fco.design_EmRes == 8782) /* map to MT ss */
    {
       if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_MT]) ||
                 (if_state.symbolset.ss_last_code[SYMBOLSET_MT] < chId))
           return 0;
       ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_MT] +
                      (chId - if_state.symbolset.ss_first_code[SYMBOLSET_MT]) );
DBG1("GET_xWORD(ptr):0x%lx\r\n",GET_xWORD(ptr));
       return (GET_xWORD(ptr));
    }
    else
#endif

    fst_type =  fst_type; /* quiet compiler*/

#if (TT_RDR || FCO_RDR)
    {
    if((chId < if_state.symbolset.ss_first_code[SYMBOLSET_TT]) ||
              (if_state.symbolset.ss_last_code[SYMBOLSET_TT] < chId))
        return 0;
    ptr = (LPUB8)(if_state.symbolset.pss_entry[SYMBOLSET_TT] +
                   (chId - if_state.symbolset.ss_first_code[SYMBOLSET_TT]) );
    return (GET_xWORD(ptr));
    }
#endif

#endif    /* (IF_RDR || PST1_RDR)  &&  (TT_RDR || FCO_RDR) */

}


/*------------------*/
/*     SYMinit      */
/*------------------*/

#if defined (ANSI_DEFS)
GLOBAL UW16  SYMinit (FSP0)
#else
GLOBAL UW16
SYMinit ()
#endif
{
#if ROM

    if_state.symbolset.curssnum = 0;     /* no symbol set is loaded  */
    return SUCCESS;

#else     /*  Disk based version */

    SW16         ii;
    UW16 status;
#ifdef AGFADEBUG
    LPUB8        ss;
    SL32          dir_size, num_symsets;
#endif

    DBG("init_symbol_set()\n");

    if_state.symbolset.curssnum = 0;               /* no symbol set is loaded  */
    for (ii=0; ii<NSS_FILES; ii++)
        if_state.symbolset.hss_directory[ii] = 0;

#if (IF_RDR | PST1_RDR)
    if_state.shortPath[SYMBOLSET_IF] = pathIF;
    status = SYMinit_ReadDir(FSA FC_IF_TYPE);
    if_state.symbol_set_symm[SYMBOLSET_IF] = if_state.symbol_setIF;
    if (status)  return status;
#endif

#if (TT_RDR || FCO_RDR)
    if_state.shortPath[SYMBOLSET_TT] = pathTT;
    status = SYMinit_ReadDir(FSA FC_TT_TYPE);
    if_state.symbol_set_symm[SYMBOLSET_TT] = if_state.symbol_setTT;
    if (status)  return status;
#endif

#if FCO_RDR
    if_state.shortPath[SYMBOLSET_MT] = pathMT;
    status = SYMinit_ReadDir(FSA FC_FCO_TYPE);
    if_state.symbol_set_symm[SYMBOLSET_MT] = if_state.symbol_setMT;
    if (status)  return status;
#endif


#ifdef AGFADEBUG
    if(UFST_get_debug(FSA0))
        {
        SL32 jj;
        for (jj=0; jj<NSS_FILES; jj++)
          {
            if (if_state.symbolset.hss_directory[jj])
            {
                ss = (LPUB8)MEMptr(if_state.symbolset.hss_directory[jj]);
                num_symsets = GET_xWORD_OFF(ss, SSD_NSS);
                dir_size = GET_xWORD_OFF(ss, SSD_DIRSIZE);
                ss += SSD_DOFF;
                for(ii=0; ii<num_symsets; ii++, ss += dir_size)
                    DBG5("    %c%c:  first= %u   num= %u   offset= %lu\n",
                            ss[SSD_CODE], ss[SSD_CODE+1],
                            GET_xWORD_OFF(ss, SSD_FIRSTC),
                            GET_xWORD_OFF(ss, SSD_NUMC),
                            GET_xLONG_OFF(ss, SSD_OFF) );
            }
          }
        }
#endif  /* AGFADEBUG */

    return status;

#endif  /*  !ROM  */
}


#if DISK_FONTS
#if defined (ANSI_DEFS)
MLOCAL UW16  SYMinit_ReadDir (FSP SL32 fst_type)
#else
MLOCAL UW16
SYMinit_ReadDir (fst_type)
  SL32  fst_type;    /* FC_IF_TYPE, FC_PST1_TYPE, FC_TT_TYPE, or FC_FCO_TYPE */
#endif
{
    UB8          buffer[SSD_DOFF];
    SL32          dir_size;
    SL32          fd;        /* symbol set file */
    MEM_HANDLE  *hndl=NULL;
    SL32          num_symsets;
#if USING_16_BIT_DOS     /* 16 bit platform */
    UW16         ssdir_size;
#else                     /* 32 bit platform */
    SL32          ssdir_size;
#endif
    SB8          pathname[PATHNAMELEN] = "\0";

#if (IF_RDR || PST1_RDR)
    if (fst_type == FC_IF_TYPE)
        {           /* build full pathname; get pointer to IF symbol sets */
        buildpath (pathname, if_state.ufstPath, if_state.shortPath[SYMBOLSET_IF]);
        hndl = &if_state.symbolset.hss_directory[SYMBOLSET_IF];
        }
#endif

#if (TT_RDR || FCO_RDR)
    if (fst_type == FC_TT_TYPE)
        {           /* build full pathname; get pointer to TT symbol sets */
        buildpath (pathname, if_state.ufstPath, if_state.shortPath[SYMBOLSET_TT]);
        hndl = &if_state.symbolset.hss_directory[SYMBOLSET_TT];
        }
#endif

#if FCO_RDR
    if (fst_type == FC_FCO_TYPE)
        {           /* build full pathname; get pointer to MT symbol sets */
        buildpath (pathname, if_state.ufstPath, if_state.shortPath[SYMBOLSET_MT]);
        hndl = &if_state.symbolset.hss_directory[SYMBOLSET_MT];
        }
#endif


  /* Open symbol set file and read number of entries */
    if ((fd = OPEN(pathname, O_READFLAGS)) == -1)
    {
#if NO_SYMSET_MAPPING
        /* assume that user is using NO_SYMSET_MAPPING exclusively -
            don't treat this as an error */
        DBG("Symbol set file uif.ss, utt.ss or umt.ss not found - continuing anyway\n");
        return SUCCESS;
#else
        DBG("Symbol set file uif.ss, utt.ss or umt.ss not found\n");
        return ERR_no_symbol_set;
#endif
    }

    if(READF(fd, (LPSB8)buffer, SSD_DOFF) != SSD_DOFF)
    {
        DBG("    read error\n");
        CLOSE(fd);
        return ERR_rd_symbol_set;
    }

  /*  Get symbol set directory memory; read directory. There's one more
   *  because of the dummy entry at the end.
   */
    num_symsets = GET_xWORD_OFF(buffer, SSD_NSS);
    dir_size = GET_xWORD_OFF(buffer, SSD_DIRSIZE);
    ssdir_size = (num_symsets + 1) * dir_size + SSD_DOFF;
    *hndl = FMalloc_rd(FSA fd, ssdir_size, 0L);
    CLOSE(fd);
    if(!(*hndl))
    {
        DBG("    loading symbol set directory failed\n");
        return ERR_rd_symbol_set;
    }

    return SUCCESS;
}
#endif  /*  DISK_FONTS  */


/*------------------*/
/*     SYMexit      */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID  SYMexit(FSP0)
#else
GLOBAL VOID
SYMexit()
#endif
{
#if DISK_FONTS
#if (IF_RDR | PST1_RDR)
    BUFfree(FSA if_state.symbolset.hss_directory[SYMBOLSET_IF]);
#endif
#if (TT_RDR || FCO_RDR)
    BUFfree(FSA if_state.symbolset.hss_directory[SYMBOLSET_TT]);
#endif
#if FCO_RDR
    BUFfree(FSA if_state.symbolset.hss_directory[SYMBOLSET_MT]);
#endif
#endif
}

/*------------------*/
/*    SYMnew        */
/*------------------*/
/*  If font f's symbol set is different than the current symbol set,
 *  then read in the new symbol set and set f's first_code and
 *  last_code fields.
 *  Errors:
 *       Can't find symbol set referenced by f->ss_code
 *       Can't open symbol set file if.ss
 *       Can't seek to new symbol set in if.ss
 *       Can't read new symbol set from if.ss
 */

#if defined (ANSI_DEFS)
GLOBAL BOOLEAN SYMnew(FSP UW16 new_ss_num, UW16 fstType)
#else
GLOBAL BOOLEAN
SYMnew(new_ss_num, fstType)
  UW16  new_ss_num;
  UW16  fstType;    /* FC_IF_TYPE, FC_PST1_TYPE, FC_TT_TYPE, or FC_FCO_TYPE */
#endif
{
    SL32           i,ii,jj; /* keb */
    register SL32  nsn;
    SL32           num_symsets;
    SL32           dir_size;
    LPUB8         pss;
#if !ROM                          /* Okay here. jwd, 11-8-99. */
    SB8           pathname[PATHNAMELEN] = "\0";
    LPSB8         fname;
    UL32          ss_offset;      /* offset to new symbol set */
    SL32           ss_size;        /* size of new symbol set   */
    SL32           ssf;            /* symbol set file handle   */
    BOOLEAN       ok;
#endif

  /* Change symbol set if necessary */

    if (new_ss_num != if_state.symbolset.curssnum)
        {
        /* set to invalid symbolset in case we fail */
        if_state.symbolset.curssnum = 0;

        DBG1("New symbol set %u\n", new_ss_num);

#if CFF_RDR
        /*
         * don't bother trying to find the matching symbol set for
         * CFF encoding or SID use, characters determined differently 
         * than codes found in the symbol set...
         */
        if ( (new_ss_num == CFFENCODING) ||
             (new_ss_num == CFFCHARSET) )
          return TRUE;
#endif  /* CFF_RDR) */

#if USE_PS_ARRAY
        /*
         * don't bother trying to find the matching symbol set for
         * Type 1 encoding, characters determined differently 
         * than codes found in the symbol set...
         */
        if (new_ss_num == T1ENCODING)
          return TRUE;
#endif  /* USE_PS_ARRAY */

#if ASIAN_ENCODING     /* 3/11/93 maib */
        /*
         * don't bother trying to find the matching symbol set for
         * Asian encodings: characters determined differently 
         * than codes found in the symbol set...
         */
         /* also do this for raw-glyph-index mode (sandra, Dec 2000) */
        if ( is_it_Asian (new_ss_num) ) 
          return TRUE;
#endif /* ASIAN_ENCODING */

/**************************************************/
/* Search symbol set directory for new symbol set */
/* This loop loads both IF and TT symbol sets if both FSTs are enabled.
 * What we really want to do is
 *   1) if FST = IF, load only the IF symbol set.
 *   2) if FST = TT, and TT_PLUGINS == 2 or 0, load only the TT symbol set.
 *   3) if FST = TT, and TT_PLUGINS == 1, load both symbol sets.
 * By the way, whatever goes for IF goes for PST1 too.
 */
        for (jj=0; jj<NSS_FILES; jj++)
            {
            if_state.symbolset.ss_first_code[jj] = 0;
            if_state.symbolset.ss_last_code[jj]  = 0;

            /* For a simultaneous Disk/ROM Solution, the symbol sets will */
            /* need to be stored in ROM only.  UFST looks for the symbol */
            /* set files in only one place. jwd, 11-8-99. */

#if ROM        /* actually, (DISK_FONTS && ROM) || ROM */
            pss = if_state.symbolset.pss_directory[jj];
#else   /*  !ROM */
            pss = (LPUB8)MEMptr(if_state.symbolset.hss_directory[jj]);
            fname = if_state.shortPath[jj];
#endif /* ROM */

DBG4("pss:%lx, SSD_NSS:%d, SSD_DIRSIZE:%d, SSD_DOFF:%d\r\n",pss, SSD_NSS, SSD_DIRSIZE, SSD_DOFF);

            num_symsets = GET_xWORD_OFF(pss, SSD_NSS);
            dir_size = GET_xWORD_OFF(pss, SSD_DIRSIZE);
            pss += SSD_DOFF;

/* new_ss_num is the representation of a two-byte string such as "DT"
 * or "VI". Therefore its value as a 16-bit word is PLATFORM-DEPENDENT.
 * "nsn" is platform-independent. */

            nsn = GET_xWORD(&new_ss_num);

#if 0   /* jwd, 09/23/02. */
#if PCLEO_RDR
            if ( (fstType & FC_EXTERN_TYPE) && if_state.PCL_font_type == PCL_BOUND_FONT)
               nsn = new_ss_num;  /* don't swap if pcleo */    /* if bound pcleo - 03-28-02 jfd */
#endif  /* PCLEO_RDR */
#endif  /* jwd, 09/23/02  */

            for (i=0; i<num_symsets;  i++, pss += dir_size)
                {
                if (nsn == (GET_xWORD_OFF(pss, SSD_CODE)) )
                    break;
                }
            if (i == num_symsets)    /* if the function argument does not */
                {                    /* match any of the symbol set codes */
                DBG("    symbol set not found\n");
#if !((IF_RDR || PST1_RDR) && (TT_RDR || FCO_RDR))   /* IF-only or TT-only, but not both */
                fstType=fstType;     /* quiet compiler */
                return FALSE;        /* required symbol set not found */
#else
                if ( (fstType & FC_FONTTYPE_MASK) == FC_TT_TYPE  ||
                       (fstType & FC_FONTTYPE_MASK) == FC_FCO_TYPE )
                    {
                    if (jj == SYMBOLSET_TT)
                        return FALSE;   /* required symbol set not found */
                    }
                else
                    {
                    if (jj == SYMBOLSET_IF)
                        return FALSE;   /* required symbol set not found */
                    }
                continue;   /* ==> for (jj=0; jj<NSS_FILES; jj++) */
#endif
                }

#if ROM        /* actually, (DISK_FONTS && ROM) || ROM */
            if_state.symbolset.pss_entry[jj] = (LPUW16)(if_state.symbolset.pss_directory[jj] +
                            GET_xLONG_OFF(pss, SSD_OFF));

#else /* !ROM */
            if_state.symbolset.pss_entry[jj] = (LPUW16)(if_state.symbol_set_symm[jj]);   /* @@@ This can be optimized -- mby 10/08/92 */
            ss_offset = GET_xLONG_OFF(pss, SSD_OFF);
            ss_size = (SL32)(GET_xLONG_OFF(pss, (dir_size + SSD_OFF)) - ss_offset);
            DBG1("    symbol set size %lu\n", ss_size);

          /* Build full pathname; read in new symbol set.  */
            buildpath (pathname, if_state.ufstPath, fname);
            if ((ssf = OPEN(pathname, O_READFLAGS)) == -1)
                {
                DBG("Symbol set file ss.s not found\n");
                return FALSE;
                }
            ok = FMseek_read(FSA ssf, ss_offset, ss_size, (LPSB8)if_state.symbol_set_symm[jj]);
            CLOSE(ssf);
            if (!ok)
                {
                DBG("    symbol set read failed\n");
                return FALSE;
                }

#endif  /*  ROM  */

            if_state.symbolset.curssnum = new_ss_num;   /*  Success- a new symbol set */
            if_state.symbolset.ss_first_code[jj] = GET_xWORD_OFF(pss, SSD_FIRSTC);
            if_state.symbolset.ss_last_code[jj]  = if_state.symbolset.ss_first_code[jj] +
                                          GET_xWORD_OFF(pss, SSD_NUMC) - 1;
            if_state.symbolset.ss_symSetCode[jj] = GET_xWORD_OFF(pss, SSD_SYMCODE);
            if_state.symbolset.ss_type[jj]       = GET_xWORD_OFF(pss, SSD_TYPE);
            if_state.symbolset.ss_class[jj]      = GET_xWORD_OFF(pss, SSD_CLASS);
            for (ii=0; ii<8; ii++)
            if_state.symbolset.ss_requirements[jj][ii] = GET_xBYTE_OFF(pss,SSD_REQUIRE+ii);

#if TT_RDR
            if (jj == SYMBOLSET_TT)
                {
                if_state.symbolset.tt_platID     = GET_xWORD_OFF(pss, SSD_PLID);
                if_state.symbolset.tt_specID     = GET_xWORD_OFF(pss, SSD_SPID);
                }
#endif
            }       /* for (jj=0; jj<NSS_FILES; jj++)    */

        }       /* if(new_ss_num != if_state.symbolset.curssnum)  */
    return TRUE;
}

/*------------------*/
/*    SYMnoMap      */  /* mby, 06-06-94 */
/*------------------*/

/*
 *  If symbol set word in fontcontext is 0x8000, it means the PCLExO has a
 *  downloaded symbol set. CGIFfont calls this function instead of SYMnew.
 *  Fills in symbolset.curssnum, symbolset.ss_{first|last}_code[]
 */

#define GET_WORD( destp, srcp )   MEMCPY( (SB8 *)(destp), (SB8 *)(srcp), 2 );

#if defined (ANSI_DEFS)
GLOBAL BOOLEAN SYMnoMap( FSP LPUB8 font_hdr, UW16 fstType )
#else
GLOBAL BOOLEAN SYMnoMap( font_hdr, fstType )
    LPUB8 font_hdr;
    UW16  fstType;
#endif
{
   SL32     q=0;

   /* The original code required the preprocessor code to evaluate */
   /* and then set 'q' to the correct value. The following code is */
   /* a little more straightforward, and uses the fstType value.   */

   /* No MicroType case exists at this point, as MicroType is only */
   /* an embedded format; no download format exists, and this code */
   /* would not be executed.                                       */

#if (IF_RDR || PST1_RDR)
   if (((fstType & FC_FONTTYPE_MASK) == FC_IF_TYPE) || 
       ((fstType & FC_FONTTYPE_MASK) == FC_PST1_TYPE))
      q = SYMBOLSET_IF;
#endif

#if TT_RDR
   if ((fstType & FC_FONTTYPE_MASK) == FC_TT_TYPE)
      q = SYMBOLSET_TT;
#endif

    if_state.symbolset.curssnum = 0;

#if PCLEO_RDR     /* 06-13-94 */
    if (fstType & FC_EXTERN_TYPE)
    {
        if ( (fstType & FC_FONTTYPE_MASK) == FC_IF_TYPE )
        {
            GET_WORD(&if_state.symbolset.ss_first_code[q], font_hdr + FIRST_CODE);
            GET_WORD(&if_state.symbolset.ss_last_code[q], font_hdr + LAST_CODE);
        }
        else
        {
            if_state.symbolset.ss_first_code[q] = GET_xWORD_OFF(font_hdr, FIRST_CODE);
            if_state.symbolset.ss_last_code[q] = GET_xWORD_OFF(font_hdr,LAST_CODE);
        }
        return TRUE;
    }
#endif  /* PCLEO_RDR */

    return TRUE;
}

t0ikan.txt  、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/PSI/T0IKAN.C_V   1.41   Aug 22 2003 09:19:24   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/PSI/T0IKAN.C_V  $ 
 * 
 *    Rev 1.41   Aug 22 2003 09:19:24   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.40   Jul 23 2003 17:37:20   Galejs
 * "hexascii" field uses enum value now, not boolean
 * 
 *    Rev 1.39   Jun 23 2003 15:20:58   Galejs
 * ufstport.h
 * 
 *    Rev 1.38   14 Sep 2001 10:47:42   JOE
 * Changed conditional compiles for ps0load_font() and hex_or_bin()
 * from DISK_FONTS to PST1_DISK (by jfd and dz).
 * 
 *    Rev 1.37   May 04 2001 15:39:44   Galejs
 * data-type cleanup
 * 
 *    Rev 1.36   Nov 28 2000 18:25:12   Galejs
 * minor conditional-compile fix
 * 
 *    Rev 1.35   23 Mar 2000 11:30:44   JOE
 * DISK/ROM changes (by jwd).
 * 
 *    Rev 1.34   10 Feb 2000 15:49:42   AL
 * Removed PST1_ROM
 * 
 *    Rev 1.33   Aug 13 1999 16:11:58   galejs
 * include-file changes
 * 
 *    Rev 1.32   29 Jul 1999 17:08:14   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.31   09 Feb 1999 15:01:28   GALEJS
 * remove unused includes
 * 
 *    Rev 1.30   21 Jan 1999 16:12:46   GALEJS
 * standardize #include tests (plus compile fix in ps0set_char())
 * 
 *    Rev 1.29   13 Jan 1999 14:25:42   MARTIN
 * Removed SHOWINPUT to resolve MSVC warning.
 * 
 *    Rev 1.28   16 Sep 1998 20:04:14   GALEJS
 * get rid of obsolete MIPS code
 * 
 *    Rev 1.27   22 Jun 1998 18:28:42   GALEJS
 * modify UnicodeToJis call for reentrancy
 * 
 *    Rev 1.26   17 Jun 1998 16:53:12   GALEJS
 * /psi now fully reentrant
 * 
 *    Rev 1.25   15 Jun 1998 12:36:56   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.24   29 May 1998 18:03:04   GALEJS
 * move MLOCALs, GLOBALs, swap macros into if_type.h
 * 
 *    Rev 1.23   31 Mar 1998 18:01:30   GALEJS
 * shareinc.h now requires <stdio.h>
 * 
 *    Rev 1.22   26 Mar 1998 17:00:52   GALEJS
 * include-file changes
 * 
 *    Rev 1.21   20 Mar 1998 12:12:32   GALEJS
 * 64-bit port
 * 
 *    Rev 1.20   10 Feb 1998 17:08:42   GALEJS
 * conditionally-compile some code as Disk-only
 * 
 *    Rev 1.19   15 Jan 1997 11:37:12   DAVID
 * Removed PST1_PCLEOI option as part of project to trim ufst.
 * 
 *    Rev 1.18   07 Apr 1995 10:26:50   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.17   02 Dec 1994 21:08:54   MIKE
 * KSC (YAN).
 * 
 *    Rev 1.16   22 Jun 1994 11:00:04   JOE
 * In ps0set_char(), added mapping function call for UNICODE encoding.
 * Added hooks for BIG5, TCA, KJ and GB encodings (future).
 * 
 *    Rev 1.15   22 Apr 1994 14:45:16   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.14   22 Mar 1994 10:16:44   JOE 
 * Modified ps0set_char() for ROM support.
 * 
 *    Rev 1.13   08 Dec 1993 19:00:28   ROB
 * General cleanup for MSDOS, FLAT, OS2.
 * 
 *    Rev 1.12   01 Dec 1993 09:27:56   JOE 
 * Changed KANJI_ENCODING to ASIAN_ENCODING.
 * 
 *    Rev 1.11   01 Jul 1993 15:41:34   JOE
 * 
 * EUC KANJI support.
 * Fixed function prototypes for LINT_ARGS.
 * Changed t0setup() from GLOBAL to MLOCAL.
 * 
 *    Rev 1.10   24 Jun 1993 16:54:42   JOE
 * 
 * In hex_or_bin(), changed "name" to "tfntname" to resolve compiler error.
 * 
 *    Rev 1.9   21 Jun 1993 09:18:14   JOE
 * Corrected function prototype for ps0set_char() for !LINT_ARGS.
 * Added missing ";" to function prototype for hex_or_bin().
 * 
 *    Rev 1.8   15 Jun 1993 15:35:20   ROB
 * Move 'hexascii' to type 1 bucket.
 * 
 *    Rev 1.7   15 Jun 1993 11:09:12   JOE
 * Moved "vxWorks.h" before "port.h" to resolve conflicts.
 * 
 *    Rev 1.6   14 Jun 1993 10:42:46   ROB
 * Changes for 'JIS' mapping.
 * 
 *    Rev 1.5   09 Jun 1993 16:32:52   JOE
 * Changed all references to "char" to "SB8" for transportability.
 * 
 *    Rev 1.4   08 Jun 1993 18:32:58   ROB
 * Fix for ANSI requirement when not enabled -need to have some code generated.
 * 
 *    Rev 1.3   28 Apr 1993 14:46:30   LISA
 * Added keyword information to top of file.
 * 
*/
/* $Date:   Aug 22 2003 09:19:24  $ */
/* t0ik.c */
 

/*
REVISION HISTORY
-----------------------------------------------------------------------
15-Mar-93  rs  Original file created.
24-Mar-93  rs  Add support for half width Romaji and Kana.
27-Mar-93  rs  Add error codes & uses define 'KANJI_ENCODING'.
24-May-93  rs  Add 'int T0IKAN' to satisfy ANSI requirements.
09-Jun-93  jfd Changed all references to "char" to "SB8" for transportability.
15-Jun-93  jfd Moved "vxWorks.h" before "port.h" to resolve conflicts.
15-Jun-93  rs  Move 'hexascii' to type 1 bucket.
16-Jun-93  jfd Corrected function prototype for ps0set_char() for !LINT_ARGS.
           Added missing ";" to function prototype for hex_or_bin().
24-Jun-93  jfd In hex_or_bin(), changed "name" to "tfntname" to resolve
               compiler error.
30-Jun-93 jfd/gy
               EUC KANJI support.
               Fixed function prototypes for LINT_ARGS.
               Changed t0setup() from GLOBAL to MLOCAL.
01-Dec-93 jfd  Changed KANJI_ENCODING to ASIAN_ENCODING.
08-Dec-93 rs   General cleanup - MSDOS & OS2.
22-Mar-94 jfd  Modified ps0set_char() for ROM support.
22-Jun-94 jfd  In ps0set_char(), added mapping function call for
               UNICODE. Added hooks for BIG5, TCA, KJ and GB encodings
               for the future.
15-Jan-97 dlk  Removed PST1_PCLEOI option as part of project to trim ufst.
10-Feb-98 slg  Definitions of tfntname[], ps0load_font(), hex_or_bin() are now
               Disk-modes-only; 2 casts added in ps0set_char()
09-Mar-98 slg  Don't use "long" dcls (incorrect if 64-bit platform)
26-May-98 slg  Move SWAP macros and MLOCALs into if_type.h.
21-Jan-99 slg  Add compile fix in ps0set_char() - if !(ASIAN_ENCODING && PST1_ROM),
                we need to test for !ROM now, rather than assuming we are in
                DISK mode (as we might have CFF_ROM instead)
28-Jul-99 ks   Changed DEBUG compiler directive to AGFADEBUG. 
10-Feb-00 awr  Removed PST1_ROM
23-Mar-00 jwd  Changed !ROM conditional compiles to DISK_FONTS, to allow Disk/ROM 
               functionality.
14-Sep-01 jfd/dz Changed conditional compile for ps0load_font() and hex_or_bin()
                 from DISK_FONTS to PST1_DISK.
*/

#include "cgconfig.h"

#if PST1_RDR && ASIAN_ENCODING /* conditional compile entire module */ 

#ifdef VXWORKS
#include "vxWorks.h"
#endif
#include <stdio.h>

#include "ufstport.h"
#include "shareinc.h"

#include <math.h>
#include <string.h>

#if MAYBE_FCNTL_H
#include <fcntl.h>
#endif

#if MAYBE_FCNTL_HIF_H
#include <fcntl.h>
#endif

#if MAYBE_IO_H
#include <io.h>         /* close() */
#endif

#if MAYBE_UNISTD_H
#include <unistd.h>
#endif

#if MAYBE_MALLOC_H
#include    <malloc.h>
#endif

#include <stdlib.h> /* need for 'abort()' i.e. ASSERT */

#include "dbg_ufst.h"

#include "mixmodel.h"
#include "cgmacros.h"

#include "t1itype1.h"
#include "t1isyntx.h"
#include "t1iproto.h"
#include "t0itype0.h"


#ifdef LINT_ARGS

MLOCAL SL32           hex_or_bin (FSP0);
MLOCAL SL32           t0setup (FSP0);

#else /* no LINT_ARGS */

MLOCAL SL32           hex_or_bin ();
MLOCAL SL32           t0setup ();
#endif /* LINT_ARGS */

#if defined AGFADEBUG
CONST MLOCAL SB8 tErrLoad[] = "Error loading type 0 file:";
#endif /* AGFADEBUG */

#if PST1_DISK    /* 09-14-01 jfd Changed from DISK_FONTS */
#if defined (ANSI_DEFS)
GLOBAL SL32 ps0load_font (FSP LPSB8 basename)
#else
GLOBAL SL32 ps0load_font (basename)
LPSB8 basename;
#endif
{

LPSB8 pfn;
SL32 status;
LPSL32 pCOD;
PCDATASTR   pcharstring;

    DBG ("\nps0load_font\n");

   if_state.t0flag = 0;  /* init our flag */
   STRCPY (if_state.gpxb->pathname, basename); /* copy font base name to bucket */
   STRCPY (if_state.tfntname, basename); /* copy font base name to working buff */
   pfn = &if_state.tfntname[STRLEN (if_state.tfntname)];

   /*
      Verify that the top level pgf file is available
   */
   STRCAT (if_state.tfntname, "h.pgf");  /* make the top level pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_H0file);
   }
   CLOSE (if_state.gpxb->fh);    /* close top level pgf file */

   /*
      Load the Romaji pgf file
   */
   STRCPY (pfn, "sr.pgf");  /* make the Romaji pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_R0file);
   }

   status = hex_or_bin (FSA0);
   if (status)
      return (status); /* closes file */

   /*
      Process the Romaji pgf file
   */
   if (reader (FSA0) <= 0)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_rdfont);
   }

   /*
      Allocate memory for the encoding array
      [0]      = R
      [1]      = K
      [2..129] = SJIS rows x80 .. xff

      Init all members to -1
   */
   if_state.gpps->hCODarray = BUFalloc (FSA (SL32)(130 * sizeof (SL32)));
  if (!if_state.gpps->hCODarray)
  {
    DBG ("Error allocating type 0 encoding array");
     return (ERR_psi_type0_codarr);
  }
  pCOD = (LPSL32)MEMptr (if_state.gpps->hCODarray);
   for (status = 0; status < 130; status++)
      pCOD[status] = -1L;

   status = t0setup (FSA0);
   /*
     Close the Romaji pgf file!
   */
   if (if_state.gpxb->fh != -1)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
   }
   if (status)
      return (status);

   /*
      Load the Kana pgf file
   */
   STRCPY (pfn, "sk.pgf");  /* make the Kana pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_K0file);
   }

   status = hex_or_bin (FSA0);
   if (status)
      return (status); /* closes file */

   /*
      Process the Kana pgf file
   */
   if (reader (FSA0) <= 0)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_rdfont);
   }

   status = t0setup (FSA0);
   /*
     Close the Kana pgf file!
   */
   if (if_state.gpxb->fh != -1)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
   }
   if (status)
      return (status);

   /*
      Load the Shift JIS level 1 pgf file
   */
   STRCPY (pfn, "sa.pgf");  /* make the Shift JIS level 1 pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_A0file);
   }

   status = hex_or_bin (FSA0);
   if (status)
      return (status); /* closes file */

   /*
      Process the Shift JIS level 1 pgf file
   */
   if (reader (FSA0) <= 0)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_rdfont);
   }

   status = t0setup (FSA0);
   /*
     Close the Shift JIS level 1 pgf file!
   */
   if (if_state.gpxb->fh != -1)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
   }
   if (status)
      return (status);


   /*
      Load the Shift JIS level 2 pgf file
   */
   STRCPY (pfn, "sb.pgf");  /* make the Shift JIS level 2 pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_B0file);
   }

   status = hex_or_bin (FSA0);
   if (status)
      return (status); /* closes file */

   /*
      Process the Shift JIS level 2 pgf file
   */
   if (reader (FSA0) <= 0)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_rdfont);
   }

   status = t0setup (FSA0);
   /*
     Close the Shift JIS level 2 pgf file!
   */
   if (if_state.gpxb->fh != -1)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
   }
   if (status)
      return (status);


   /*
      Load the User Gaiji pgf file
   */
   STRCPY (pfn, "ug.pgf");  /* make the User Gaiji pgf font name */
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_UG0file);
   }

   status = hex_or_bin (FSA0);
   if (status)
      return (status); /* closes file */

   /*
      Process the User Gaiji pgf file
   */
   if (reader (FSA0) <= 0)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_rdfont);
   }

   status = t0setup (FSA0);
   /*
     Close the User Gaiji pgf file!
   */
   if (if_state.gpxb->fh != -1)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
   }
   if (status)
      return (status);

   /*
     Allocate memory for the charstring structure
     We will only be storing 1 outline at a time
   */
   if_state.gpps->hcharstrings = BUFalloc (FSA (SL32)(sizeof (CDATASTR)));
   if (!if_state.gpps->hcharstrings)
   {
        DBG ("Error allocating type 0 hcharstrings");
        return (ERR_psi_CharStr_mem);
   }
   pcharstring = (PCDATASTR)MEMptr (if_state.gpps->hcharstrings);
   if_state.gpps->n_chars = 1;              /* only 1 char at a time */
   if_state.gpps->curr_char = 0;
   /*
        Init charstring array so we can free it later
   */
   pcharstring->hname = NIL_MH;
   pcharstring->hdata = NIL_MH;

   return (SUCCESS);
}
#endif    /* PST1_DISK */

#if PST1_DISK   /* jwd, 3/23/00. This function only usable for disk modes */
                /* jfd/dz 09-14-01 Changed from DISK_FONTS */
#if defined (ANSI_DEFS)
MLOCAL SL32 hex_or_bin (FSP0)
#else
MLOCAL SL32 hex_or_bin ()
#endif
/*
   Determine if this is a binary or hex ascii font.
   For binary input, throw away header (8001XXXXXXXX).

   return (SUCCESS) if no error, else error code
   sets 'hexascii' = 0 for binary, 1 for hex ascii file
*/
{
UB8 tmpbuf[8];  /* large enough for section header */

   if (READF (if_state.gpxb->fh, (SB8 *)tmpbuf, 6) != 6)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
      DBG1 ("psload_font() - error reading file:%s\n", if_state.tfntname);
      return (ERR_psi_rdfont);
   }
   if (tmpbuf[0] == 0x80)
      if_state.gpps->hexascii = T2ASCII;
   else if (tmpbuf[0] < '%' && tmpbuf[3] > 0 && tmpbuf[3] < 5)
      if_state.gpps->hexascii = CFF;
   else    /* hex ascii font, put back the data we just threw away */
   {
      if_state.gpps->hexascii = T1HEXFONT;
      LSEEK (if_state.gpxb->fh, 0L, SEEK_SET);
   }
   return (SUCCESS);
}
#endif    /* PST1_DISK */


#if defined (ANSI_DEFS)
MLOCAL SL32 t0setup (FSP0)
#else
MLOCAL SL32 t0setup ()
#endif
/*
get the tables set up correctly
*/
{
SL32 FlipFlop_ON = 0, wstat, status;
SL32  PGOffset;
LPSL32 pCOD = (LPSL32)MEMptr (if_state.gpps->hCODarray);
LPUB8  tpch;


    DBG ("\nt0setup()\n");

   while ((wstat = t1scanone (FSA0)) > 0)
   {
      if (wstat < 0)
         return (ERR_psi_rdfont);
      if (!wstat)
         return (SUCCESS); /* EOF */

      if (if_state.psiw.elt.type == TYPE_NAME)
      {
         if (streq ("FontMatrix", (LPSB8)if_state.psiw.token) && !(if_state.t0flag & T0F_MATRIX))
         {
            status = get_matrix (FSA0);
            if (status)
               return (status);
            if_state.t0flag |= T0F_MATRIX;
         }
         else if (streq ("BlueValues", (LPSB8)if_state.psiw.token) && !if_state.gpps->numbblues)
         {
            status = get_blues (FSA0);
            if (status)
               return (status);
         }
         else if (streq ("StdHW", (LPSB8)if_state.psiw.token) && !if_state.gpps->inStdHW) 
         {
            status = get_stdhw (FSA0);
            if (status)
               return (status);
         }
         else if (streq ("StdVW", (LPSB8)if_state.psiw.token) && !if_state.gpps->inStdVW) 
         {
            status = get_stdvw (FSA0);
            if (status)
               return (status);
         }
         else if (streq ("PGOffsets", (LPSB8)if_state.psiw.token)) 
         {
            if (FlipFlop_ON || t1scanone (FSA0) < 0 || if_state.psiw.elt.type != TYPE_INTEGER)
            {
               DBG ("Error scanning type 0 PGOffset");
               return (ERR_psi_type0_PGOffset);
            }
            PGOffset = if_state.psiw.elt.intval;
            FlipFlop_ON = 1;
         }
         else if (streq ("FontName", (LPSB8)if_state.psiw.token)) 
         {
            if (!FlipFlop_ON)
               continue;
            if (t1scanone (FSA0) < 0 || if_state.psiw.elt.type != TYPE_NAME)
            {
               DBG ("Error scanning type 0 FontName");
               return (ERR_psi_type0_FontName);
            }
            /*
               Cases include:
                   'R' - Romaji
                   'K' - Kana
                   else reverse search for '-', then value of SJ row
            */
            tpch = &if_state.psiw.token[STRLEN ((FILECHAR *)if_state.psiw.token) - 1];
            switch (*tpch)
            {
                case 'R':
                     pCOD[COD_ROFF] = PGOffset;
                     break;
                case 'K':
                     pCOD[COD_KOFF] = PGOffset;
                     break;
                default:
                     while ((SB8)(*tpch) != '-')
                           tpch--;
                     tpch++;
                     sscanf ((LPSB8)tpch, "%x", &FlipFlop_ON);
                     pCOD[FlipFlop_ON - COD_SJOFF] = PGOffset;
                     break;
            } /* switch */
            FlipFlop_ON = 0;
         }
      } /* if (if_state.psiw.elt.type == TYPE_NAME) */
   } /* while (t1scanone () > 0) */
  return (SUCCESS);
}

#if defined (ANSI_DEFS)
GLOBAL VOID free_COD (FSP PPS_BUCK lpps)
#else
GLOBAL VOID free_COD (lpps)
PPS_BUCK lpps;
#endif
{
   if (lpps->hCODarray)
   {
      BUFfree (FSA lpps->hCODarray);
   }

   return ;
}

#if defined (ANSI_DEFS)
GLOBAL UW16 ps0set_char (FSP UW16 chId)
#else
GLOBAL UW16 ps0set_char (chId)
UW16 chId;
#endif
{
LPSL32 pCOD = (LPSL32)MEMptr (if_state.gpps->hCODarray);
PCDATASTR   pcharstring = (PCDATASTR)MEMptr (if_state.gpps->hcharstrings);
SL32   tmpl;
UW16   tmpw;
#if (UNICODE_IN && JIS_ENCODING)
UW16   tmpw2;
#endif
UB8    hibyte, lobyte;

    DBG ("\nps0set_char()\n");

   switch (if_state.gpxb->cur_ssnum)
   {
#if JIS_ENCODING
       case JIS:
         tmpw = JisToSJis (chId);
         break;
#endif
#if SJIS_ENCODING
       case SHIFT_JIS:
         tmpw = chId;
         break;
#endif
#if EUC_ENCODING
       case EUC:
       tmpw = EucToSJis(chId);
         break;
#endif
#if (UNICODE_IN && JIS_ENCODING)
       case UNICODE:
         if (!(tmpw2 = UnicodeToJis(FSA chId)))   /* unicode-to-jis first */
           return ERR_INVALID_MAPPING;
         tmpw  = JisToSJis(tmpw2); /* jis-to-sjis second   */
         break;
#endif
#if (BIG5_ENCODING || TCA_ENCODING || K_ENCODING || GB_ENCODING)
       case BIG5:
       case TCA:
       case KSC:
       case GB:
         DBG ("Invalid transformation\n");
         return (99); /* transformation not valid */
#endif
       default:
        DBG ("Invalid type 0 symbol set\n");
        return (ERR_psi_type0_noSymSet); /* symbol set not supported */
   }


    /*
      Map the chId to an offset in the COD file
      This code is for a font laid out in a SJIS format
    */
    hibyte = tmpw >> 8;
    lobyte = tmpw & 0xff;
    if (hibyte <= 0x7f)                         /* Romaji */
    {
       tmpl = pCOD[0];
       if (tmpl != -1)
           tmpl += (hibyte * 6);                /* get to this column */
    }
    else if (hibyte >= 0xa0 && hibyte <= 0xdf)   /* Kana */
    {
        tmpl = pCOD[1];
        if (tmpl != -1)
            tmpl += ((hibyte - 0xa0) * 6);        /* get to this column */
    }
    else if ((hibyte >= 0x81 && hibyte <= 0x9f)   /* Shift JIS 1 */
            || (hibyte >= 0xe0 && hibyte <= 0xef))/* Shift JIS 2 */
    {
          tmpl = pCOD[hibyte - COD_SJOFF];
          if (tmpl != -1)
              tmpl += ((lobyte - 64) * 6);   /* get to this column */
    }
    else
    {
        return (ERR_psi_type0_generic); /* chId does not map to a character */
    }

    if (tmpl == -1)                     /* row not in font */
        return (ERR_psi_type0_RowMissing);

#if DISK_FONTS  /* jwd, 3/23/00. */
  {
  LPUB8  pub;
  SB8    tmpbuf[6];

    /*
      Get the offset to the CSA from the COD
    */
    STRCPY (if_state.tfntname, if_state.gpxb->pathname);
    STRCAT (if_state.tfntname, ".cod");
   if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
   if (if_state.gpxb->fh == -1)
   {
      DBG2 ("%s%s", tErrLoad, if_state.tfntname);
      return (ERR_psi_open_CODfile);  /* error opening COD file */
   }
   if (LSEEK (if_state.gpxb->fh, tmpl, SEEK_SET) != tmpl)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
      DBG1 ("ps0set_char() - error reading:%s\n", if_state.tfntname);
      return (ERR_psi_access_CODfile); /* error accessing COD file */
   }
   if (READF (if_state.gpxb->fh, (LPSB8)tmpbuf, 6) != 6)
   {
      CLOSE (if_state.gpxb->fh);
      if_state.gpxb->fh = -1;
      DBG1 ("ps0set_char() - error reading:%s\n", if_state.tfntname);
      return (ERR_psi_access_CODfile); /* error accessing COD file */
   }
   tmpl = GET_xLONG (tmpbuf);           /* get offset to CSA */
   tmpw = GET_xWORD_OFF(tmpbuf, 4) - 1; /* get length of outline */
   CLOSE (if_state.gpxb->fh);    /* close cod file */

   /*
     Open the CSA and seek to this outline
   */
    STRCPY (if_state.tfntname, if_state.gpxb->pathname);
    STRCAT (if_state.tfntname, ".csa");
    if_state.gpxb->fh = OPEN (if_state.tfntname, O_READFLAGS);
    if (if_state.gpxb->fh == -1)
    {
        DBG2 ("%s%s", tErrLoad, if_state.tfntname);
        return (ERR_psi_open_CSAfile);  /* error opening CSA file */
    }
    if (LSEEK (if_state.gpxb->fh, tmpl, SEEK_SET) != tmpl)
    {
        DBG ("Error seeking in CSA");
        return (ERR_psi_access_CSAfile);  /* error accessing CSA file */
    }

    /*
        Allocate memory for the character outline
        But first free the previous character
    */
    if (pcharstring->hdata)
       BUFfree (FSA pcharstring->hdata);
    if_state.gpps->pthis_charstring = NULL;
    pcharstring->hdata = BUFalloc (FSA (SL32)tmpw);
    if (!pcharstring->hdata)
    {
        CLOSE (if_state.gpxb->fh);    /* close csa file */
        if_state.gpxb->fh = -1;
        return (ERR_psi_Chardat_mem);  /* error allocating char data memory */
    }
    pub = (LPUB8)MEMptr (pcharstring->hdata);
    if (READF (if_state.gpxb->fh, pub, tmpw) != tmpw)
    {
        CLOSE (if_state.gpxb->fh);
        if_state.gpxb->fh = -1;
        DBG1 ("ps0set_char() - error reading:%s\n", if_state.tfntname);
        return (ERR_psi_access_CSAfile);/* error reading char outline in CSA */
    }
    pcharstring->len = tmpw;
    pcharstring->decrypted = 0;

    if_state.gpps->pthis_charstring = pcharstring;
    CLOSE (if_state.gpxb->fh);
    if_state.gpxb->fh = -1;
  }
#endif

    return (SUCCESS);
}
#endif /* PST1_RDR && ASIAN_ENCODING */

t0itype0.h  、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/PSI/T0ITYPE0.H_V   1.6   Aug 22 2003 09:19:24   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/PSI/T0ITYPE0.H_V  $ 
 * 
 *    Rev 1.6   Aug 22 2003 09:19:24   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.5   Sep 23 2002 13:57:36   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.4   04 Oct 1996 09:20:52   JOE
 * Removed CTRL-Z at end of file.
 * 
 *    Rev 1.3   07 Apr 1995 10:32:50   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.2   22 Apr 1994 14:49:32   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.1   28 Apr 1993 14:47:16   LISA
 * Added keyword information to top of file.
 * 
*/
/* $Date:   Aug 22 2003 09:19:24  $ */
/* t0itype0.h */
 

/*
REVISION HISTORY
-----------------------------------------------------------------------
15-Mar-93  rs  Original file created.

*/

#ifndef __T0ITYPE0__
#define __T0ITYPE0__

/*
   Define COD array offsets
*/
#define  COD_ROFF    0                 /* Romaji offset */
#define  COD_KOFF    1                 /* Kana offset */
#define  COD_SJOFF   127               /* Shift JIS offset */

/*
   t0flags definitions
*/
#define  T0F_MATRIX  1                 /* got Matrix */

#endif    /* __T0ITYPE0__    */


t1idecod.txt   、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

/* Copyright (C) 2004 Agfa Monotype Corporation. All rights reserved. */

/* $Header:   I:/BULL/URIP/RTS/PSI/T1IDECOD.C_V   1.123   Sep 27 2004 16:22:18   dugganj  $ */
/* $Log:   I:/BULL/URIP/RTS/PSI/T1IDECOD.C_V  $ 
 * 
 *    Rev 1.123   Sep 27 2004 16:22:18   dugganj
 * Added multithread support.
 * 
 *    Rev 1.122   Sep 21 2004 11:15:26   galejss
 * fix compile error (psptr needed if ROM)
 * 
 *    Rev 1.121   Aug 10 2004 18:27:48   galejss
 * changes for runtime no-symset-mapping (including a rewrite of much of psset_char)
 * 
 *    Rev 1.120   Jul 16 2004 14:03:34   galejss
 * use new defines USE_PS_SYMSET, USE_PS_ARRAY, PS_RESIDENT in tests;
 * changes to support mixed disk/rom builds for PS
 * 
 *    Rev 1.119   Apr 26 2004 18:44:50   GalejsS
 * remove obsolete Type0 code, old version of hinting code
 * 
 *    Rev 1.118   Oct 17 2003 15:22:48   Galejs
 * no-idea-why-it-works fix for MSVC 6.0 compile warning
 * 
 *    Rev 1.117   Sep 26 2003 16:47:10   Galejs
 * use new FPOP, FPOPX, FPUSH macros (with optional stackchecking if PS_ERRORCHECK is enabled)
 * 
 *    Rev 1.116   Aug 27 2003 18:54:56   Galejs
 * check for null "transptr" in psmake_gaso_and_stats
 * 
 *    Rev 1.115   Aug 08 2003 18:00:56   Galejs
 * add non-ANSI_DEFS headers for psf_read() and psf_seek()
 * 
 *    Rev 1.114   Jul 28 2003 18:02:34   Galejs
 * call IXopen_file() instead of psf_open(); don't null out if_state.gpxb (risky)
 * 
 *    Rev 1.113   Jun 23 2003 15:16:44   Galejs
 * ufstport.h
 * 
 *    Rev 1.112   Nov 26 2002 18:43:28   Galejs
 * add casts to all MEMptr() calls
 * 
 *    Rev 1.111   Sep 30 2002 11:46:28   Galejs
 * 32-bit charcode support (for rjl)
 * 
 *    Rev 1.110   Sep 26 2002 19:31:22   Galejs
 * fix a datatype for INT_MEM; remove SUPERDEBUG code
 * 
 *    Rev 1.109   14 Sep 2001 10:32:24   JOE
 * Changed conditional compiles for psf_open(), psf_close(), psf_read()
 * and psf_seek() from PST1_DISK to PST1_DISK || PST1_SFNTI || CFF_DISK.
 * 
 *    Rev 1.108   31 Aug 2001 13:38:50   JOE
 * Cleaned up description below.
 * 
 *    Rev 1.107   31 Aug 2001 13:08:14   JOE
 * Make PCLchId2ptr() and PCLglyphID2ptr() reentrant (by slg).
 * 
 *    Rev 1.106   Jul 20 2001 16:52:12   Galejs
 * fix align-to-SW16 logic for 64-bit pointers
 * 
 *    Rev 1.105   Jul 03 2001 11:24:30   Galejs
 * in t1e_SBW case, pop the y-escapement even though we're not using it
 * 
 *    Rev 1.104   Jun 28 2001 19:58:16   Galejs
 * NULL return in finddata() is OK if there are no chars in the font (customer-supplied fix)
 * 
 *    Rev 1.103   Jun 18 2001 10:34:10   Paul
 * changes for NEW_PS_HINTS
 * 
 *    Rev 1.102   05 Jun 2001 13:12:42   JOE
 * In psload_font(), resolved compiled error when building with
 * CFF disabled.
 * 
 *    Rev 1.101   04 Jun 2001 10:25:16   JOE
 * OpenType changes.
 * 
 *    Rev 1.100   May 21 2001 20:45:10   Galejs
 * integrate PST1_RAM option; clean up CFF_ROM implementation
 * 
 *    Rev 1.99   May 04 2001 15:37:08   Galejs
 * data-type cleanup
 * 
 *    Rev 1.98   Apr 02 2001 14:25:14   Al
 * Return error if PS path doesn't start with moveto
 * 
 *    Rev 1.97   Nov 22 2000 16:18:22   Galejs
 * new parameters for rewritten vstem6()
 * 
 *    Rev 1.96   Mar 24 2000 17:28:44   galejs
 * fix conditional-compile problems, clean up warnings
 * 
 *    Rev 1.95   11 Feb 2000 16:41:28   AL
 * Disk and ROM can both be active
 * 
 *    Rev 1.94   10 Feb 2000 15:37:20   AL
 * Removed PST1_ROM
 * 
 *    Rev 1.93   Jan 28 2000 16:15:34   galejs
 * fix compile errors when PST1_ROM && NO_SYMSET_MAPPING
 * 
 *    Rev 1.92   Aug 13 1999 16:11:58   galejs
 * include-file changes
 * 
 *    Rev 1.91   29 Jul 1999 17:06:52   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.90   14 Apr 1999 12:52:14   DAVID
 * Changed conditional compile for 'mapidx' local variable
 * to eliminate compiler warnings.
 * 
 *    Rev 1.89   10 Mar 1999 14:03:04   DAVID
 * In psget_width(), made reference to type2char() conditional on
 * CFF_RDR.
 * 
 *    Rev 1.88   10 Mar 1999 11:02:50   DAVID
 * In psget_width(), enabled CFF access to widths via conditional
 * call to type2char().
 * 
 *    Rev 1.87   24 Feb 1999 14:39:38   JOE
 * In psget_width(), return error (0) if font is a cff font (by keb).
 * 
 *    Rev 1.86   18 Feb 1999 09:11:38   JOE
 * In psload_font(), moved default operand settings to CFF processing block.
 * 
 *    Rev 1.85   11 Feb 1999 10:07:36   JOE
 * In psload_font(), set default opcode operand values for those not
 * covered in cffsetup().
 * 
 *    Rev 1.84   09 Feb 1999 14:20:06   GALEJS
 * remove unused includes
 * 
 *    Rev 1.83   27 Jan 1999 17:55:38   GALEJS
 * make test for EXTERN PSdata[] consistent with definition
 * 
 *    Rev 1.82   21 Jan 1999 17:46:40   GALEJS
 * standardize #include tests
 * 
 *    Rev 1.81   20 Jan 1999 13:30:36   DAVID
 * Fixed typo - 'CFF_DSK' to 'CFF_DISK'.
 * 
 *    Rev 1.80   16 Sep 1998 20:01:20   GALEJS
 * get rid of obsolete MIPS code
 * 
 *    Rev 1.79   16 Sep 1998 15:51:48   DAVID
 * In 'type1char()', initialized closepath_called = 1.
 * 
 *    Rev 1.78   16 Sep 1998 15:29:22   DAVID
 * In psload_font(), changed '==' to '=' in assignment.
 * 
 *    Rev 1.77   11 Sep 1998 12:06:16   GALEJS
 * add O_RDONLY define (for Microware build only)
 * 
 *    Rev 1.76   10 Sep 1998 19:12:38   GALEJS
 * compiler fixes (add 4 casts)
 * 
 *    Rev 1.75   02 Sep 1998 18:49:46   GALEJS
 * fix compile problems for CFF_ROM
 * 
 *    Rev 1.74   27 Aug 1998 16:01:50   AL
 * Implemented othersubrs 18
 * 
 *    Rev 1.73   24 Aug 1998 13:47:38   AL
 * Fixed defualt mm instance problems
 * 
 *    Rev 1.72   21 Aug 1998 12:14:26   AL
 * Fixed hex ascii file format
 * 
 *    Rev 1.71   13 Aug 1998 08:56:48   DAVID
 * Moved 'psf-open',_close,_read,_seek, and 'psrom_xxx' function
 * definition block from 'cffsupp.c' to here so PST1_DISK (without)
 * CFF_RDR will compile.
 * 
 *    Rev 1.70   12 Aug 1998 15:15:24   DAVID
 * In 'ps_is_same()' added conditional CFF_RDR for CFF nameInSet
 * test.
 * 
 *    Rev 1.69   06 Aug 1998 16:25:06   AL
 * CFF rom, multiple master and bug fixes
 * 
 *    Rev 1.68   27 Jul 1998 15:27:46   AL
 * cff cleanup
 * 
 *    Rev 1.67   22 Jul 1998 16:38:46   GALEJS
 * fix typo in psrom_set_char() (missing "if_state.")
 * 
 *    Rev 1.66   22 Jul 1998 15:57:22   AL
 * Removed uneeded call to psunload_font() and file close in psload_font()
 * 
 *    Rev 1.65   21 Jul 1998 16:07:52   AL
 * Corrected ps_is_same() to compare against bucket inputDV[]
 * 
 *    Rev 1.64   20 Jul 1998 15:18:40   AL
 * Added ps_is_same() for multiple master and CFF support
 * 
 *    Rev 1.63   10 Jul 1998 11:39:10   AL
 * conditionally compile CFF code
 * 
 *    Rev 1.62   09 Jul 1998 13:34:34   DAVID
 * In psset_char(), added code to close open file in CFF handling.
 * 
 *    Rev 1.61   08 Jul 1998 19:22:56   DAVID
 * Integrated new CFF processing into UFST code base.

*    Rev 1.60   17 Jun 1998 17:02:28   GALEJS
* /psi is now fully reentrant

*    Rev 1.59   15 Jun 1998 12:18:28   GALEJS
* remove MULTICALLER code; include-file changes

*    Rev 1.58   29 May 1998 18:47:12   GALEJS
* move MLOCALs, GLOBALs, and swap macros into if_type.h

*    Rev 1.57   15 Apr 1998 18:06:40   GALEJS
* hchar_buf in IF_STATE now

*    Rev 1.56   26 Mar 1998 17:05:14   GALEJS
* kanji.h included in shareinc.h

*    Rev 1.55   24 Mar 1998 17:21:02   GALEJS
* include-file changes

*    Rev 1.54   10 Feb 1998 17:07:20   GALEJS
* conditionally-compile some code as Disk-only

*    Rev 1.53   31 Jul 1997 16:24:42   JOE
* Resolved unreferenced variables warnings (by Jimmy).

*    Rev 1.52   17 Jul 1997 10:56:22   JOE 
* Changed local variables "cc1" and "cc2" from int to UW16 to
* resolve type mismatch warnings (by Jimmy).

*    Rev 1.51   15 Jul 1997 10:51:36   AL
* Pseudo bold via outlines

*    Rev 1.50   15 Jan 1997 11:48:48   DAVID 
* Removed PST1_PCLEOI option as part of project to trim ufst.

*    Rev 1.49   16 Oct 1996 16:15:58   JOE
* In othersubr(), push current x and  y onto stack to fix accent
* rendering and placement problem.

*    Rev 1.48   13 Sep 1996 16:53:44   MIKE
* "fc_format" replaces "rom_font" in BUCKET structure

*    Rev 1.47   15 Mar 1996 10:07:12   MIKE
* PCLflag

*    Rev 1.46   23 Feb 1996 16:21:54   MERRILL
* removed lly, yadv and fix return(success)

*    Rev 1.45   18 Apr 1995 16:57:50   JOE
* In psset_char() and psrom_set_char(), added support for the removal
*   of symbol set mapping.
* Conditionally compiled PSdata[] and cm_cgidToIndex() based on
*   !NO_SYMSET_MAPPING.

*    Rev 1.44   07 Apr 1995 10:27:26   LISA
* Changed copyright from Miles Inc. to Bayer Corp.

*    Rev 1.43   02 Dec 1994 21:09:14   YAN
* KSC.

*    Rev 1.42   22 Jun 1994 11:03:44   JOE
* In psload_font() and psset_char(), when checking for type of ASIAN
* encoding, added checks for UNICODE, BIG5, TCA and GB.

*    Rev 1.41   22 Apr 1994 16:12:16   JOE
* Changed conditional compile statement prior to including <hif.h>
* to #if (_AM29K && !UNIX) to resolve UNIX Metaware compiler error.

*    Rev 1.40   22 Apr 1994 14:45:44   LISA
* Made modifications to copyright/disclaimer notice.

*    Rev 1.39   22 Mar 1994 10:20:54   JOE
* In PSROMload_font() and psset_char(), added Type 0 support.

*    Rev 1.38   25 Feb 1994 09:47:02   JOE
* AM29K changes for ROM support to fix compiler errors in PSROMfinddata(),
* psrom_set_char() and PSROMload_font().

*    Rev 1.37   09 Feb 1994 14:00:48   JOE
* More _AM29K changes.

*    Rev 1.36   02 Feb 1994 10:12:04   JOE
* AM29K changes.

*    Rev 1.35   08 Dec 1993 19:00:20   ROB
* General cleanup for MSDOS, FLAT, OS2.

*    Rev 1.34   01 Dec 1993 09:31:42   JOE
* Changed KANJI_ENCODING to ASIAN_ENCODING.

*    Rev 1.33   19 Nov 1993 11:26:46   JOE
* In psset_char(), expanded conditional compile statement used for setting
* "if_state.char_buf = MEMptr(hchar_buf)" to include IF_PCLEOI.

*    Rev 1.32   16 Nov 1993 14:33:02   JOE
* In type1char(), added support for 'special' test font.

*    Rev 1.31   27 Oct 1993 19:49:56   MIKE
* if MULTICALLER, call PCLchId2ptr() with callerID argument.

*    Rev 1.30   25 Oct 1993 10:50:48   JOE
* In othersubr(), "fpush" the current point onto the stack because
* "t1e_SETCURPT" attempts to pop it later.
* In tye1char(), only simulate "closepath" if !record.

*    Rev 1.29   15 Oct 1993 10:04:08   JOE
* In type1char(), replaced disabled code associated with "t1e_SETCURPT"
* (Fmoveto) with code to set the current point (curx,cury) to the 2
* values popped off the stack to fix incorrect placement of accents on
* several compound characters of "special" Type 1 fonts.

*    Rev 1.28   14 Oct 1993 14:56:24   JOE
* In type1char(), when processing a MOVETO, check if a closepath was
* executed for the previous loop. If not, execute the closepath so that
* the number of loops in the character will be updated properly.

*    Rev 1.27   06 Oct 1993 09:43:20   JOE

* In type1char(), cast call to GETECHAR() as UL32 because "<< 16" shift
* was causing the hi-word to be lost.

*    Rev 1.26   29 Sep 1993 12:04:30   JOE

* In psload_font(), initialize "gpps->FontBBox[]".

*    Rev 1.25   16 Aug 1993 16:11:58   JOE
* In psrom_set_char(), conditionally compiled block of code pertaining
* to "cur_ssnum != T1ENCODING" based on USE_UFST_MAPPING to resolve
* compiler error.

*    Rev 1.24   16 Aug 1993 10:58:20   JOE
* In psrom_set_char(), processing encoding array mapping table as SW16's
* instead of SB8's.
* In psload_font(), conditionally compiling psunload_font() calls based
* on USE_JUMP_TABLES.

*    Rev 1.23   13 Aug 1993 17:54:14   JOE

* In PSROMload_font(), added support for reading in offset to encoding
* array table "hencodearray".
* In same routine, no longer swapping in place.
* In psrom_set_char(), added encoding array support.

*    Rev 1.22   09 Aug 1993 10:29:30   JOE
* In PSROM_load_font(), changed the way Blue values and StemSnap values
* are processed from ROM. Only the number of values stored are read in, 
* rather than the max number.
* In same routine, was not loading bot_blues[] correctly from 
* other_blues[].

*    Rev 1.21   02 Aug 1993 16:17:12   JOE
* In type1char(), was not checking for PS ROM input when processing
* "t1_CALLSUBR" subr.

*    Rev 1.20   02 Aug 1993 09:45:48   JOE
* Added PS ROM support changes.

*    Rev 1.19   26 Jul 1993 11:47:34   ROB
* Add 'constant' variables 'FPZERO' & 'FPONEHALF' to 'psload_font()'.

*    Rev 1.18   13 Jul 1993 13:05:38   JOE
* Set "iT1IDECOD" = 0 if !PST1_RDR.

*    Rev 1.17   01 Jul 1993 15:34:04   JOE
* EUC KANJI support.

*    Rev 1.16   01 Jul 1993 14:28:02   MAIB
* fixed prototype

*    Rev 1.15   15 Jun 1993 11:44:06   ROB
* Move 'hexasciiflg' to type 1 bucket. Handle binary fonts w/o header.

*    Rev 1.14   14 Jun 1993 17:13:02   ROB
* Type 1 encoding array support.

*    Rev 1.13   09 Jun 1993 14:43:42   JOE
* Changed all references to "char" to "SB8" for transportability.

*    Rev 1.12   08 Jun 1993 18:06:14   ROB
* Pipeline upgrade for type 1 quality improvements, mmaster support &
* generic type 1 soft font downloader support.
*
*    Rev 1.11   30 Apr 1993 15:51:46   ROB
* Change default BlueScale value from .0395 to .039625 per B&W 'psload_font()'.
*
*    Rev 1.10   29 Mar 1993 11:01:50   ROB
* Kanji cleanup.

*    Rev 1.9   25 Mar 1993 11:13:20   ROB
* Improve quality on italic & oblique stems.
*
*    Rev 1.8   19 Mar 1993 11:40:02   JOE
* **ROB** Changes for Kanji support.
*
*    Rev 1.7   03 Mar 1993 19:19:52   ROB
* Utilize StemSnapH & StemSnapV hints for stem processing.

*    Rev 1.6   01 Mar 1993 16:06:48   JOE

* In psset_char(), make sure char_buf is pointing to the static buffer
* and not to a previous reference to a character in ROM (like a plugin).

*    Rev 1.5   15 Feb 1993 09:08:54   JOE
* Changed all occurrences of READ to READF due to conflict with VXWorks.

*    Rev 1.4   12 Feb 1993 15:45:56   JOE
* VXWorks support.

*    Rev 1.3   04 Feb 1993 14:04:08   JOE
* In psget_width(), compensate for rounding when PS is converted to
* 8782-based.
*
*    Rev 1.2   07 Jan 1993 08:44:08   JOE
* ANSI C function declaration changes.

*    Rev 1.1   14 Dec 1992 10:01:10   LISA
* Made change to Log keyword
*
*    Rev 1.0   10 Dec 1992 09:22:08   LISA
* Initial revision.
*/
/* $Date:   Sep 27 2004 16:22:18  $ */
/* t1idecod.c */
/***********************************************************************
*                                                                      *
*
*
*            Copyright (c) 1989, 1990, 1991 by                         *
*            Pipeline Associates, Inc., Morris Plains, NJ              *
*                     All rights reserved.                             *
*                                                                      *
*   This software is furnished under a license and may be used and     *
*   copied  only  in accordance with the terms of such license and     *
*   with the  inclusion  of  the  above  copyright  notice.   This     *
*   software  or  any  other copies thereof may not be provided or     *
*   otherwise made available to any other person except as allowed     *
*   under   license.  No  title to and ownership of the software is    *
*   hereby transferred.                                                *
*                                                                      *
*   This software is proprietary to Pipeline Associates, Inc., and     *
*   is not to be disclosed without written permission from Pipeline    *
*   Associates, Inc.                                                   *
*                                                                      *
************************************************************************/
/*
REVISION HISTORY
-----------------------------------------------------------------------
pre-historic    Version 1.0 -- original
pre-historic    Version 1.1 -- minor cleanup
pre-historic    Version 1.3 -- got rid of split_bez
09/27/91  rs    Original file created from Pipeline Associates 't1decode.c'.
11/18/91  rs   Modify for binary or hex ascii font input.
12/02/91  rs   Error handling cleanup.
12/16/91  rs   Change argument stack from UWORD to LONG (for 32 bit div).
01/22/92  rs   Subdivide() now calls 'ras_lineto()' directly.
01/23/92  awr  Added translation to psrender()
01/28/92  rs   Add PBUCKET to psrender() calling args.
01/29/92  rs   Fix error return for compound chars in finddata(). Clean up
error return codes. Remove 'render()'.
02/06/92  rs   Optimization of font loading. Modify 'psset_char()' to call
'more_charstrings()' if character not loaded.
03/02/92  rs   Fix from Pipeline for HSBW bbox problem. There should be no
MOVETO associated with the HSBW re:B&W book.
03/17/92  rs   Cleanup of 'invalid assigns'.
03/19/92  rs   Add PostScript PCLEO reader support 'PST1_PCLEOI'.
03/23/92  ss   Added conditional compile of "sys/..." includes.
04/03/92  rs   Portability cleanup (see port.h).
05/01/92  rs   Fix in 'psset_char()' - deref nil handle 'cptr->hname' causes
problem on Sparc.
05/06/92  ss   Moved #endif to col 1 for SUN.
05/08/92  rs   PS PCLEO integration - #include "t1ipcleo.h".
Add macro 'fpopx()' to clean up warnings.
05/21/92  jfd  In psrender(), when calling "ras_start_char()", pass
a PVOID argument.
05/21/92  rs    Add character mapping support for various symbol sets.
05/27/92  rs   Modify 'finddata()' to always use standard encoding to find
a PostScript compound character part.
06/02/92  jfd  Added function "estimate_ps_outline()" to estimate memory
required to generate a PS outline.
Added EXTERN olstats (used by outline functions).
Wherever "gpcs->" stores a value, store the same value in
"olstats.".
06/04/92  jfd  In psrender(), when calling "pras->ras_start_char(), pass
"&olstats".
Also in psrender(), check type of outline requested and call
either ras_cubeto() (if cubic) or Subdivide() (if linear).
Return error if quadratic is requested.
6/5/92   ss   Changed decoding and unputflag from SW16 to int
to match GLOBAL define (in t1iscan.c)
6/8/92   jfd  Removed all references to "olstats".
In psrender(), check return status from "ras_start_char()".
In psmake_gaso_and_stats(), reset counters "ct_lineto",
"ct_quadto" and "ct_cubeto".
06/11/92  rs/jd Update error codes.
06/21/92  awr  Changed calls to output functions
06/22/92  jfd  Changed last two arguments for "psrender()" from SL32 
to INTR.
06/25/92  rs   Add support for 'true' 32 bit segments (INTR).
06/29/92  awr  Merged all versions of estimate_outline()
1 Jul 92  ss   Conditionally compile stdlib for !MIPS.  This may also be
relevant for other UNIX SysV systems.
6 Jul 92  jfd  Added "psget_width()" function. (Disabled for now.)
8 Jul 92  jfd/rs Modified type1char() to support width only.
07/10/92  jfd  In psrender(), if quadratic outline is requested, return
error because it is not supported by PS. 
If linear is requested but not installed, return error.
If cubic is requested but not installed, return error.
07/11/92  awr  Replaced bmras_cubeto() with AGFA version in raster.c
07/21/92  awr  Conditional compile changes.
30-Aug-92 rs   Optimize use of char_buf for gaso's.
04-Sep-92 jfd  Removed call to obsolete functifon "cm_ixToPSName()".
In "psset_char()", loading "char_name" directly from
PSdata[] array.
23-Sep-92 jfd  INTEL960 conditional compile changes.
15-Oct-92 mby  SYMmap() is called with 2 arguments in psset_char().
22-Nov-92 rs   Port to Macintosh - include files.
07-Jan-93 jfd  ANSI C function declaratioon changes.
04-Feb-93 jfd  In psget_width(), compensate for rounding when PS is 
converted to 8782-based.
08-Feb-93 jfd  VXWorks support.
15-Feb-93 jfd  Changed READ to READF due to conflict with VXWorks.
01-Mar-93 ss/jfd/dbk
In psset_char(), make sure char_buf is pointing to the static
buffer and not to a previous reference to a character in ROM
(like a plugin).
02-Mar-93 rs   Utilize 'StemSnapH' & 'StemSnapV' to process a stem hint.
15-Mar-93 rs   Modifications for type 0 fonts (JIS_ENCODING).
24-Mar-93 rs   Modify 'type1char()' to improve stem intelligence on fonts
(courier oblique) with negative stem widths.
27-Mar-93 rs   Fix Kanji defines per cgconfig.h (KANJI_ENCODING).
30-Apr-93 rs   Change default value of 'BlueScale' from .0395 to .039625
as spec'd in the B&W.
Version 1.9 -- structured for folding into PowerPage
Version 3.0 -- added new OtherSubrs for Multiple Master support
4/10/92 (PHW) -- added bbox check at end for chars with no data
4/14/92 (PHW) -- added sbw command for Windows 3.1
7/7/92  (SGK) -- added OtherSubrs 14-17 for MM fonts
7/11/92  (PHW) -- changed weights from float to long
7/13/92  (SGK) -- changed blend routines to work with > 2 design axes
9/9/92  (PHW) -- initialize mins and maxes
9/15/92  (PHW) -- added debugging output
1/4/93   (SGK) -- reset argsptr on entry (for Genoa)
14-May-93 rs   Integrate Pipeline upgrade.
04-Jun-93 jfd  In psset_char(), added support for using either Type 1
encoding or symbol set.
06-Jun-93 rs   Add MultiMaster support.
09-Jun-93 jfd  Changed all references to "char" to "SB8" for transportability.
15-Jun-93 rs   Change refs to 'hexasciiflg' to 'gpps->hexascii'.
01-Jul-93 maib removed prototype from blend() non-lint declaration
30-Jun-93 jfd/gy
EUC KANJI support.
13-Jul-93 jfd  Set "iT1IDECOD" = 0 if !PST1_RDR.
23-Jul-93 rs   Add constant variables FPZERO & FPONEHALF in psload_font().
02-Aug-93 jfd  Added PS ROM support changes.
02-Aug-93 jfd  In type1char(), was not checking for PS ROM input when
processing "t1_CALLSUBR" subr.
04-Aug-93 jfd  In PSROM_load_font(), changed the way Blue values and
StemSnap values are processed from ROM. Only the number
of values stored are read in, rather than the max number.
06-Aug-93 jfd  In PSSROMload_font(), was not loading bot_blues[] correctly
from other_blues[].
13-Aug-93 jfd  In PSROMload_font(), added support for reading in offset
to encoding array table "hencodearray".
In same routine, no longer swapping in place.
In psrom_set_char(), added encoding array support.
16-Aug-93 jfd  In psrom_set_char(), processing encoding array mapping table
as SW16's instead of SB8's.
In psload_font(), conditionally calling psunload_font() based
on USE_JUMP_TABLES.
In psrom_set_char(), conditionally compiled block of code
pertaining to "cur_ssnum != T1ENCODING" based on 
USE_UFST_MAPPING to resolve compiler error.
28-Sep-93  jfd In psload_font (), initialize "gpps->FontBBox[]".
06-Oct-93  jfd In type1char(), cast call to GETECHAR() as UL32 because
"<< 16" shift was causing the hi-word to be lost.
14-Oct-93  jfd In type1char(), when processing a MOVETO, check if a 
closepath was executed for the previous loop. If not,
execute the closepath so that the number of loops in
the character will be updated properly.
15-Oct-93  jfd In type1char(), replaced disabled code associated with 
"t1e_SETCURPT" (Fmoveto) with code to set the current point
(curx,cury) to the 2 values popped off the stack to fix
incorrect placement of accents on several compound characters
of "special" Type 1 fonts.
22-Oct-93  jfd In othersubr(), "fpush" the current point onto the stack
because "t1e_SETCURPT" attempts to pop them later.
25-Oct-93  jfd In type1char(), only perform closepath if "(!record)".
26-Oct-93  mby if MULTICALLER enabled, call PCLchId2ptr() with addtional
argument. Declare uLastCallerId EXTERNAL.
16-Nov-93  jfd In type1char(), added support for 'special' test font.
19-Nov-93  jfd In psset_char(), expanded conditional compile statement
used for setting "if_state.char_buf = MEMptr (hchar_buf)"
to include "IF_PCLEOI".
01-Dec-93  jfd Changed KANJI_ENCODING to ASIAN_ENCODING.
08-Dec-93  rs  General cleanup - MSDOS & OS2.
27-Jan-94  jfd Conditionally compiled #include for fcntl.h based on
(!defined(_AM29K) || (defined(_AM29K) && |defined(UNIX))).
04-Feb-94 jfd  Conditionally compile "sys\types.h" and "sys\stat.h"
based on !_AM29K.
Including "hif.h" if _AM29K.
25-Feb-94 dbk/jfd
AM29K changes for ROM support to fix compiler errors in
PSROMfinddata(), psrom_set_char() and PSROMload_font().
22-Mar-94 jfd  In PSROMload_font() and psset_char(), added Type 0 support.
22-Apr-94 jfd  Changed conditional compile statement prior to
including <hif.h> to #if (_AM29K && !UNIX) to
resolve UNIX Metaware compiler error.
22-Jun-94 jfd  In psload_font() and psset_char(), when checking for type of 
ASIAN encoding, added checks for UNICODE, BIG5, TCA and GB.
18-Apr-95 jfd  In psset_char() and psrom_set_char(), added support for
the removal of symbol set mapping.
Conditionally compiled PSdata[] and cm_cgidToIndex()
based on !NO_SYMSET_MAPPING.
09-Sep-96 mby  Replaced PBUCKET->rom_font with PBUCKET->fc_format to fix compilation errors.
16-Sep-96 jfd  In othersubr(), push current x and y onto stack to fix 
accent rendering and placement problem.
15-Jan-97 dlk  Removed PST1_PCLEOI option as part of project to trim ufst.
10-Feb-98  slg    Some code only used if Disk mode: 2 sections in psload_font(),
finddata() definition & two calls, call to move_charstrings() 
at end of psset_char() (WARNING: last change is a bit of a hack)
26-May-98  slg    Cleanup - remove apparently-unused FPZERO, FPONEHALF;
Move SWAP macros, MLOCALs, and GLOBALs into if_type.h.
08-Jul-98 dlk  Integrated new CFF processing into UFST code base.  Changed
               copyright notice dates.
09-Jul-98 dlk  In psset_char(), added code to close open file (if it's open)
               in section to handle CFF fonts.  Fixed '69' error that appeared
               when more than 2028 file handles were used.
22-Jul-98 slg  Typo - should be "if_state.gpps->hexascii" in psrom_set_char()
12-Aug-98 dlk  In 'ps_is_same()' added conditional CFF_RDR for CFF nameInSet
               test.
12-Aug-98 dlk  Moved entire block of 'psf_xxx' and 'psrom_xxx' file functions
               from cffsupp.c to solve "unresolved external symbol _psf_close",
               seek, read, and open compile time errors - when only PST1_DISK
               was ENABLED.  'cffsupp.c' is entirely conditionally compiled on
               CFF_RDR.
27-Aug-98 awr  Implemented othersubrs() 18
02-Sep-98 slg  Fix compile problems for CFF_ROM
11-Sep-98 slg  Add O_RDONLY define (for Microware build only)
16-Sep-98 dlk  In psload_font() changed pxb->fh == -1; to pxb->fh = -1;.
16-Sep-98 dlk  In type1char(), initialize 'closepath_called' to 1.
20-Jan-99 dlk  Corrected typo in conditional - changed 'CFF_DSK' to CFF_DISK.
11-Feb-99 jfd  In psload_font(), set up default opcode operand values for 
               those not covered in cffsetup().
18-Feb-99 jfd  In psload_font(), moved default operand values to CFF
               processing block.
23-Feb-99 keb  In psget_width(), return error (0) if font is is cff format
10-Mar-99 dlk  In psget_width(), removed error return for CFF, and enabled CFF
               access to width information via conditional call to type2char().
10-Mar-99 dlk  In psget_width(), made reference to type2char() conditional on
               CFF_RDR.
14-Apr-99 dlk  Changed conditional compile of 'mapidx' variable to eliminate
               compiler warnings.
28-Jul-99 ks   Changed DEBUG compiler directive to AGFADEBUG.
28-Jan-00 slg  Fix compile errors in psrom_set_char (if NO_SYMSET_MAPPING);
               replace !ROM tests by PST1_DISK. 
10-Feb-00 awr  Removed PST1_ROM
24-Mar-00 slg  DISK_FONTS tests should be PST1_DISK; restructure psset_char()
                slightly to fix conditional compiles; fix compile warnings.
20-Nov-00 slg  Modify call to vstem6() for new version of function - pass args 
                in original form, as x and dx values
02-Apr-01 awr  Return error if PS path doesn't start with a moveto
21-May-01 slg  Integrate PST1_RAM changes; extend these changes to CFF_ROM as
                well, as a cleaner implementation of CFF_ROM (remove pretend-
                file-reads); remove unneeded calls to psf_open and psf_close 
23-May-01 jfd  In psload_font(), seek to CFF table before reading.
               In psget_width(), point to correct bucket.
05-Jun-01 jfd  In psload_font(), resolved compiler error when building with
               CFF disabled.
03-Jul-01 slg  In type1char(), t1e_SBW case, still need to pop y sidebearing
                even though we don't use it (just discard value)
20-Jul-01 slg  In psrender(), fix align-to-SW16 logic for 64-bit pointers.
30-Aug-01 slg  Make PCLchId2ptr() and PCLglyphID2Ptr() reentrant.
14-Sep-01 jfd   Changed conditional compile for psf_open(), psf_close(),
                      psf_read() and psf_seek() from PST1_DISK to 
                      PST1_DISK || PST1_SFNTI || CFF_DISK.
*/

#include "cgconfig.h"

#if PST1_RDR

#ifdef VXWORKS
#include "vxWorks.h"
#endif

#include <stdio.h>
#include <math.h>
#include <string.h>

#include "ufstport.h" 

#if MAYBE_FCNTL_H
#include <fcntl.h>
#endif

#if MAYBE_FCNTL_HIF_H
#include <fcntl.h>
#include <hif.h>  /* 2-7-94 jfd */
#endif

#if MAYBE_IO_H
#include <io.h>         /* close() */
#endif

#if MAYBE_UNISTD_H
#include <unistd.h>
#endif

#if MAYBE_MALLOC_H
#include    <malloc.h>
#endif

#include <stdlib.h> /* need for 'abort()' i.e. ASSERT */

#include "dbg_ufst.h"

#if defined (_OSK) || defined (_OS9000)
#define    O_RDONLY 0x0001
#endif

#include "shareinc.h"

#include "mixmodel.h"

#include "t1itype1.h"
#include "t1isyntx.h"
#include "t1iproto.h"
#include "cffproto.h"
#if PST1_SFNTI
#include "t1isfnt.h"
#endif

#if PS_ERRORCHECK
/* optional stackchecking (only necessary for corrupt fonts, in our opinion) */

#define FPOP(dest)    \
{    \
if (if_state.argsptr > if_state.args)  { dest = (*--if_state.argsptr); }    \
else {return ERR_psi_stack_underflow;}    \
}

#define FPOPX()    \
{    \
if (if_state.argsptr > if_state.args)  { --if_state.argsptr; }    \
else {return ERR_psi_stack_underflow;}    \
}

#define FPUSH(src)    \
{    \
if (if_state.argsptr < if_state.t1_stacklimit) { *if_state.argsptr++ = src; }    \
else {return ERR_psi_stack_overflow;}    \
}

#else

#define FPOP(x)    x = (*--if_state.argsptr)
#define FPOPX()        (--if_state.argsptr)
#define FPUSH(x)  (*if_state.argsptr++ = (x))

#endif    /* PS_ERRORCHECK */

#define GETECHAR()   ((UW16)(*edata++))

#ifdef LINT_ARGS

GLOBAL VOID estart (FSP LPUB8, SL32); 
MLOCAL SL32 type1char (FSP PCDATASTR, SL32);
MLOCAL UW16 othersubr (FSP SL32 num, SL32 arg);
#if T1MMASTER
MLOCAL SL32 blend (FSP LPSL32);
#endif

#else /* not LINT_ARGS */

GLOBAL VOID estart ();
MLOCAL SL32 type1char ();
MLOCAL UW16 othersubr ();
#if T1MMASTER
MLOCAL SL32 blend ();
#endif


#endif /* LINT_ARGS */

EXTERN LPSB8 PSdata[];

#if PST1_DISK || CFF_DISK    

#if defined (ANSI_DEFS)
GLOBAL SL32 psf_read(FSP  LPUB8 buf, SL32 cnt)
#else
GLOBAL SL32 psf_read(buf, cnt)
LPUB8 buf;
SL32 cnt;
#endif
{
    return READF(if_state.gpxb->fh, buf, cnt);
}

#if defined (ANSI_DEFS)
GLOBAL SL32 psf_seek(FSP SL32 pos, SL32 seektype)
#else
GLOBAL SL32 psf_seek(pos, seektype)
SL32 pos;
SL32 seektype;
#endif
{
    return LSEEK(if_state.gpxb->fh, pos, seektype);
}
#endif /* PST1_DISK || CFF_DISK    */


/* Check fcCur against font in bucket and retrun FALSE if they don't match.
 * Called in BUCKfind() search loop.
 */
#if defined (ANSI_DEFS)
GLOBAL BOOLEAN ps_is_same (FSP  PBUCKET b)
#else
GLOBAL BOOLEAN ps_is_same (b)
PBUCKET b;
#endif
{
#if CFF_RDR
    /* If Bucket is CFF, then match on the font name */
    if(b->p.ps.hexascii == CFF)
        if(STRNCMP(if_state.fcCur.nameInSet,
                       b->p.ps.cft.nameInSet, CFFNAMELEN) != 0)
            return FALSE;  /* match failed */
#endif /* CFF_RDR */
#if T1MMASTER
    /* If Bucket is Multiple master, check user design vector */
    if(b->p.ps.MMnaxes > 0)
    {
        SW16 i;
        for(i=0; i<b->p.ps.MMnaxes; i++)
            if(b->p.ps.inputDV[i] != if_state.fcCur.userDesignVector[i])
                return FALSE;  /* match failed */
    }
#endif
    return TRUE;
}


#if defined (ANSI_DEFS)
GLOBAL UW16 psload_font (FSP PFONT_DES name, PBUCKET pxb)
#else
GLOBAL UW16 psload_font (name, pxb)
PFONT_DES name;
PBUCKET pxb;
#endif
/*
*/
{
#if PS_RESIDENT
    UB8 tmpbuf[8];  /* large enough for section header */
    SL32 headsize, aos;
#endif
    SL32 status;
    
#if ROM
   SL32 i;
#endif
    DBG ("\npsload_font()\n");
    
    /*
    Save our parameters in globals for efficient useage
    */
    if_state.gpxb = pxb;    /* ptr to XBUCKET */
    if_state.gpps = &pxb->p.ps;   /* ptr to PS specific info in bucket */
    if_state.gpcs = (PCHAR_STATS)0;  /* just in case */
    
                                     /*
                                     Initialize variables first time through for each bucket
    */
    if_state.gpps->psiw.code   =  4330;   /* init feedback code */
    if_state.gpps->hcharstrings = if_state.gpps->hsubrs = NIL_MH;
#if USE_PS_ARRAY
    if_state.gpps->hencodearray = NIL_MH;
#endif
    if_state.gpps->lenIV = 4;
    if_state.gpps->trans = 0;
    if_state.gpps->stem_adjust = STEMWID;   /* stem adjustment cutoff */
    if_state.gpps->stem_match = STEMMATCH;  /* horiz/vert stem matching cutoff */
    if_state.gpps->stem_min = STEMMIN;      /* minimum stem width (for ForceBold) */
    if_state.gpps->overshoot = OVERSHOOT;   /* suppress overshoots < this amount */
    if_state.gpps->useblues = USEBLUES;     /* use BlueScale and BlueShift */
    if_state.gpps->hint_gravity = 0;        /* distance in pixels that hints extend */
    if_state.gpps->iBlueScale = BLUESCALE;
    if_state.gpps->iBlueShift = BLUESHIFT;
    if_state.gpps->BlueFuzz = BLUEFUZZ;
    if_state.gpps->numStemSnapH = if_state.gpps->numStemSnapV = 0;
    
    if_state.gpps->FontBBox[0] = if_state.gpps->FontBBox[1] = if_state.gpps->FontBBox[2] =
        if_state.gpps->FontBBox[3] = 0;
    
#if (T1MMASTER)
    /* Init MultiMaster */
    if_state.gpps->MMnaxes = -1;  /* # of MM axes */
    if_state.gpps->hMMblendmap = if_state.gpps->hMMblues
          = if_state.gpps->hMMotherblues = if_state.gpps->hMMblendpos = NIL_MH;
#endif /* T1MMASTER */
    
    /*
    Set up IF_CHAR struct 'c' for storing bezier data
    */
    if_state.char_buf = (LPSB8)MEMptr (if_state.hchar_buf);
    if_state.expand_buf = if_state.char_buf;
    if_state.expand_size = CHARBUFSIZE;
    
    if_state.gpps->psiw.decoding = FALSE;
    if_state.gpps->psiw.unputflag = FALSE;
                
#if PST1_SFNTI
        /*
        Ifthis is an external generic soft font, have it loaded by the
        application suplied callback soft font loader.
        */
        if (pxb->extern_font)
        {   /* PS soft font */
            status = PSSFNTload_font (FSA name);
        }
        else    /* not downloaded soft font, disk based PS font */
#endif /* PST1_SFNTI */
        {
#if PS_RESIDENT

            UL32 CFFTableOffset = 0;    /* 06-05-01 jfd */

#if TT_RDR && CFF_RDR                    /* 06-05-01 jfd */
            if (B_ISOTCFF(pxb))
                CFFTableOffset = if_state.gpps->cft.CFFTableOffset;
#endif    /* TT_RDR && CFF_RDR */

#if ROM
          /* 06-01-01 jfd - added offset to CFF table if applicable */
        if (if_state.font_access == ROM_ACCESS)
        {
            if_state.psptr = pxb->cur_font_hdr + CFFTableOffset;    /* 06-05-01 jfd */
            for (i = 0; i < 6; i++)
                tmpbuf[i] = *(if_state.psptr++);
        }
#endif    /* ROM */
#if DISK_FONTS
        if (if_state.font_access == DISK_ACCESS)
        {
            STRCPY(pxb->pathname, name);        
               status = IXopen_file(FSA (PINDEX_ENTRY)NULL, pxb);

            if(status)
            {
                pxb->fh = -1;
                if_state.gpps = (PPS_BUCK)0;
                DBG1 ("psload_font() - error opening Type 1 font:%s\n", name);
                return (ERR_psi_open_file);
            }

            psf_seek(FSA CFFTableOffset, SEEK_SET);    /* 06-05-01 jfd */

            /*  Determine if this is a T2 binary, T2 hex ascii, or CFF font    */
            /*  For a binary input, throw away header (8001XXXXXXXX).        */
            /*  for a CFF font start set up of CF structure                    */
            
            if (psf_read(FSA (LPUB8)tmpbuf, (SL32)6) != 6)
            {
                if_state.gpps = (PPS_BUCK)0;
                DBG1 ("psload_font() - error reading file:%s\n", name);
                return (ERR_psi_rdfont);
            }
        }
#endif    /* DISK_FONTS */

            if (tmpbuf[0] == 0x80)
            {
                if_state.gpps->CharstringType = 1;    /* set default */
                if_state.gpps->hexascii = T2ASCII;
            }
            /* is this a CFF font?  */
            else if(tmpbuf[0] < '%'        /* '%' =  comment character        */
                && tmpbuf[3] > 0        /* offset size = 1,2,3,4 bytes    */ 
                && tmpbuf[3] < 5 )        /* in CFF font                    */
            {
                if_state.gpps->hexascii = CFF;        /* ID type as CFF        */
                if_state.gpps->CharstringType = 2;    /* set to default        */
                headsize = tmpbuf[2];        /* CFF font header length   */
                aos      = tmpbuf[3];        /* sizeof absolute offsets    */

                /* Set up defaults for CFF input which are not covered
                 * by cffsetup()
                 */

                if_state.gpps->ForceBold          = 0;
                if_state.gpps->ForceBoldThreshold = 0;
                if_state.gpps->defaultWidthX      = 0;
                if_state.gpps->normalWidthX       = 0;
            }
            else    /* hex ascii font, put back the data we just threw away */
            {
                if_state.gpps->CharstringType = 1;    /* set default */
                if_state.gpps->hexascii = T1HEXFONT;

               /* 06-01-01 jfd - added offset to CFF table if applicable */
#if ROM
                if (if_state.font_access == ROM_ACCESS)                
                    if_state.psptr = pxb->cur_font_hdr + CFFTableOffset;
#endif
#if DISK_FONTS
                if (if_state.font_access == DISK_ACCESS)
                       psf_seek(FSA CFFTableOffset, SEEK_SET);
#endif
            }
 
            if (reader (FSA0) == 0)
            {
                if_state.gpps = (PPS_BUCK)0;
                DBG ("psload_font() - error reading file\n");
                return (ERR_psi_rdfont);
            }
            if(if_state.gpps->hexascii == CFF)
#if CFF_RDR
                status = cffsetup(FSA headsize, aos);
#else
                status = ERR_cff_not_enabled;
#endif
            else 
                status = t1setup(FSA0);
            
            if (status)
                psunload_font (FSA pxb);
            

#endif    /* PS_RESIDENT */
        } /* else (!extern_font) */
        
    if_state.gpps = (PPS_BUCK)0;
    return (status);
}

#if PS_RESIDENT
#if defined (ANSI_DEFS)
MLOCAL PCDATASTR finddata (FSP SL32 n)
#else
MLOCAL PCDATASTR finddata (n)
SL32 n;
#endif
/*
locate character data given character code (for composites)
always uses PostScript standard encoding
returns PCDATASTR for character or NULL if missing
*/
{
    register PCDATASTR cptr, cend = ((PCDATASTR)MEMptr (if_state.gpps->hcharstrings)
        + if_state.gpps->curr_char + 1);
    register LPSB8 name;
    PCDATASTR   savecptr; /* save current ptr while reading more charstrings */
    SL32   status;
    
    /*
    Pieces of compound characters must be in the standard encoding array.
    Therefore, they must be between 0 and 256. Get character name.
    */
    if (n < 0 || n > 256)
    {
        DBG1 ("finddata() bad character code:(%d)\n", n);
        return (NULL);
    }
    
    name = stdencoding[n];
    DBG1 ("name is %s\n", name);
    
    /*
    Get pointer to charstring for this character if it has been read into
    memory.
    */
    for (cptr = (PCDATASTR)MEMptr (if_state.gpps->hcharstrings); cptr < cend; ++cptr) 
      if (cptr->hname != NIL_MH)
        if (STRCMP ((LPSB8)MEMptr (cptr->hname), name) == 0)
            break;
        
        if (cptr != cend)
            return cptr;
        
            /*
            Character is not in charstrings. Perhaps it has not been loaded yet.
            Save current charstring ptr, load desired charstring & restore ptr.
        */
        if (if_state.gpps->curr_char < if_state.gpps->n_chars)
        {
            savecptr = if_state.gpps->pthis_charstring;
            status = more_charstrings (FSA name);
            cptr = if_state.gpps->pthis_charstring;
            if_state.gpps->pthis_charstring = savecptr;
        }
        if (status)
            return (NULL);  /* charstring not found */
        else return cptr;

#endif    /* PS_RESIDENT */


#if defined (ANSI_DEFS)
GLOBAL VOID estart (FSP register LPUB8 s, SL32 len)
#else
GLOBAL VOID estart (s, len)
register LPUB8 s;
SL32      len; /* change from SW16 to SL32 - 10/2/91 - rs */
#endif
/*
decrypt a string
*/
{
    register SW16  i;
    
    if_state.gpps->psiw.code = 4330;
    
    for (i = 0; i < (SW16)len; ++i) /* add cast of (SW16) - 10/2/91 - rs */
    {
        if_state.gpps->psiw.x = (UW16)*s;
        *s++ = (UB8)((if_state.gpps->psiw.x ^ (if_state.gpps->psiw.code >> 8)) & 0x00ff);
        if_state.gpps->psiw.code = 0x58bf + (if_state.gpps->psiw.code + if_state.gpps->psiw.x) * 0xce6d;
    }
}

#if defined (ANSI_DEFS)
MLOCAL SL32 type1char (FSP PCDATASTR cptr, SL32 wflag)
#else
MLOCAL SL32 type1char (cptr, wflag)
PCDATASTR cptr;
SL32       wflag;  /* 0==build character, 1==get width only */
#endif
/*
** type1char does all the hard work of decoding the Type 1 format.
** Each time it encounters a path drawing command or hint, it calls the
** relevant routine in t1hints.c.

3/20/92 - rs - Add support for PS PCLEO characters
*/
{
    register LPUB8 edata;
    register UL32 c; /* UW16 to UL32 - 12/16/91 - rs */
    SL32  arg;  /* UW16 to SL32 - 12/16/91 - rs */
    SL32  xadv=0L, savex, savey, llx=0L; /* SW16 to SL32 - 12/16/91 - rs */
    SL32  llx_accent;   /* 11-16-93 jfd */
    SW16  num, sublevel = 0;
    SL32  x1, y1, x2, y2, x3, y3;
    SL32  sx=0L, sy=0L; /* SW16 to SL32 - 12/16/91 - rs */
    SL32  composite = FALSE;
    SL32 poptmp;
    
    SL32 donecc2 = FALSE ;
    UW16 cc1, cc2 ;
    
    SL32  deltax, deltay; /* SW16 to SL32 12/16/91 - rs */
    UW16  tmp;
    UW16 inchar, inchar2;
    SL32 status;
    LPUB8   pdata;   /* add 1/3/92 - rs */
    PSUBS_STR psubrs; /* add 1/3/92 - rs */
    
#if PST1_SFNTI
    LPUB8 ph;
    SW16  Namelen, Datalen;
    UB8   Decryptflag; /* Decrypt byte */
    SL32   PCLflag = 0;
#endif
    
    
    SL32 closepath_called = 1;  /* flag indicating whether t1closepath()
                               * has been called, init this to = 1.     */
    
    SL32 seacs_called = 0;      /* 11-16-93 jfd */
    SL32 ccparts_processed = 0; /* 11-16-93 jfd */
    SL32 ccparts_needed = 0;    /* 11-16-93 jfd */
    
                               /* Incorporating array to handle mltiple SEAC commands for a given character
                               *    11-16-93 jfd
    */
    SL32 deltax_buf[4];      /* 11-16-93 jfd */
    SL32 deltay_buf[4];      /* 11-16-93 jfd */
    SL32 llx_accent_buf[4];  /* 11-16-93 jfd */
    SL32 llx_buf[4];         /* 11-16-93 jfd */
    SL32  cc2_buf[4];         /* 11-16-93 jfd */
    SL32  cc1_buf[4];         /* 11-16-93 jfd */

    if_state.argsptr = if_state.args;
    if_state.record = FALSE;   /* now used outside this function - 5/14/93 - rs */
    if_state.gpps->psiw.curx = if_state.gpps->psiw.cury = 0L; /* now used outside this function - 5/14/93 - rs */
    
#if PST1_SFNTI
    /*
    NOTE:
    The following code is to support generic downloaded soft fonts.
    It is up to the application to provide a call back loader to handle
    them. During DEBUG, we will assume that they look like PSEO's.
    */
    if (if_state.gpxb->extern_font)   /* see if this is a type 1 downloaded soft font */
    {
        PCLflag = 1;            /* indicate a downloaded soft font */
        ph = (LPUB8)((LPUB8)cptr + sizeof (PS_CHAR_HDR)); /* -> Namelen */
        UNPACK_WORD((LPUB8)&Namelen);   /* get Namelen */
        UNPACK_WORD((LPUB8)&Datalen);   /* get Datalen */
        ph += Namelen;           /* -> Data */
        Decryptflag = *(ph + Datalen); /* get Decrypt byte */
        if (!Decryptflag) /* only handle decrypted data for now */
            return (ERR_psi_pcleo_encr);
        pdata = ph;
    }
    else                     /* not PCLEO, disk based */
#endif /* PST1_SFNTI */
        {

            pdata = (LPUB8)MEMptr (cptr->hdata); /* add 1/3/92 - rs */
            if (!cptr->decrypted)
            {
                estart (FSA pdata, cptr->len);
                cptr->decrypted = TRUE;
            }
        }
        
        edata = pdata + if_state.gpps->lenIV;
        
        while (1)
        {
            inchar = GETECHAR ();
            
            if (inchar <= 0xf6)
                c = inchar;
            else
            {
                inchar2 = GETECHAR ();
                c = ((inchar << 8) | inchar2);
            }
            
            DBG1("type1char: c = 0x%x\n", c);
            if (/*(c < 0) compiler warning - 2/5/92 - rs || */ (c >= 0x20))
            {
                
                /* see if we should flush them out */
                
                if (c >= 0x20 && c < 0xf7)
                {
                    arg = (SL32)c - 0x20L - 107L;
                }
                else if (c >= 0xf700 && c < 0xfb00)
                {
                    arg = (SL32)c - 0xf700L + 108L;
                }
                else if (c >= 0xfb00 && c < 0xff00)
                {
                    arg = (-((SL32)c - 0xfb00L + 108L));
                }
                else
                {  /* next four bytes contain a long */
                    c =  (c << 24) | ((UL32)GETECHAR () << 16);  /* 10-06-93 jfd */
                    c |= GETECHAR () << 8;
                    arg = (SL32)(c | GETECHAR ());
                }
                DBG1("type1char: arg to push = 0x%x\n", arg);
                FPUSH (arg);
                continue;
            }
            
            /* opcode */
            
            switch ((SW16)(c & 0xffff))
            {
            case t1_HSTEM:  /* hstem */
                DBG ("hstem\n");
                
                FPOP(y2);
                FPOP(y1); y1 += sy;
                
                status = hstem (FSA y1, y1 + y2);
                if (status)
                    return (status);
                break;
            case t1_VSTEM:  /* vstem */
                DBG ("vstem\n");
                
                FPOP(x2);
                FPOP(x1); x1 += sx;
                
                status = vstem (FSA x1, x1 + x2);
                if (status)
                    return (status);
                break;
            case t1_YRMOVETO:  /* yrmoveto */
                FPOP(poptmp);
                if_state.gpps->psiw.cury += poptmp;
                DBG2 ("yrmoveto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                
                /* If closepath has not been executed for prevvious loop,
                * we will do it ourselves here!
                *
                *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                */
                
                if (!if_state.record)  /* 10-25-93 jfd */
                {
                    
                    if (!closepath_called)
                    {
                        savex = if_state.gpps->psiw.curx;
                        savey = if_state.gpps->psiw.cury;
                        status = t1closepath(FSA0);
                        if (status)
                            return (status);
                    }
                    else
                        closepath_called = 0;
                    
                }  /* 10-25-93 jfd */
                
                
                   /* In an interpreter environment, eliminate this "if_state.record" nonsense,
                   (i.e., it's always FALSE), since it's handled by OtherSubrs
                   calls in preparation for executing OtherSubrs[0] (FlxProc).
                */
                
                if (!if_state.record) 
                    status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                if (status)
                    return (status);
                
                break;
            case t1_RLINETO:  /* rlineto */
                FPOP(poptmp);
                if_state.gpps->psiw.cury += poptmp;
                FPOP(poptmp);
                if_state.gpps->psiw.curx += poptmp;
                DBG2 ("rlineto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                status = LINETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                if (status)
                    return (status);
                break;
            case t1_XRLINETO:  /* xrlineto (horiz line) */
                FPOP(poptmp);
                if_state.gpps->psiw.curx += poptmp;
                DBG2 ("xrlineto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                status = LINETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                if (status)
                    return (status);
                break;
            case t1_YRLINETO:  /* yrlineto (vert line) */
                FPOP(poptmp);
                if_state.gpps->psiw.cury += poptmp;
                DBG2 ("yrlineto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                status = LINETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                if (status)
                    return (status);
                break;
            case t1_RRCURVETO:  /* rcurveto */
                DBG ("rcurveto\n");
                FPOP(y3);
                FPOP(x3);
                FPOP(y2);
                FPOP(x2);
                FPOP(y1);
                FPOP(x1);
                
                x1 += if_state.gpps->psiw.curx;
                y1 += if_state.gpps->psiw.cury;
                x2 += x1;
                y2 += y1;
                x3 += x2;
                y3 += y2;
                
                DBG8 ("curveto %ld,%ld %ld,%ld %ld,%ld %ld,%ld\n",
                    if_state.gpps->psiw.curx, if_state.gpps->psiw.cury, x1, y1, x2, y2, x3, y3);
                status = CURVETO (x1, y1, x2, y2, x3, y3);
                if (status)
                    return (status);
                
                if_state.gpps->psiw.curx = x3;
                if_state.gpps->psiw.cury = y3;
                break;
            case t1_CLOSEPATH:  /* closepath */
                DBG ("closepath\n");
                /* CLOSEPATH (); error mgt:replace macro w/inline code 12/3/91 - rs */
                savex = if_state.gpps->psiw.curx;
                savey = if_state.gpps->psiw.cury;
                status = t1closepath(FSA0);
                if (status)
                    return (status);
                
                closepath_called = 1;   /* 10-13-93 jfd */
                
                status = MOVETO (savex, savey);
                if (status)
                    return (status);
                
                break;
            case t1_CALLSUBR:  /* subr */
                               /* In an interpreter environment, a lookup would be made
                               inside the Subrs array, stored inside the Private 
                dictionary, for the subroutine to execute.  */
                
                FPOP(poptmp);
                num = (SW16)(poptmp & 0xffff);
                DBG1 ("calling subr %d\n", num);
                if_state.subcalls[sublevel].data = edata;
                if_state.subcalls[sublevel++].key = if_state.gpps->psiw.code;
                if (num >= if_state.gpps->nsubs)
                {
                    DBG2 ("type1char() - subnum:%d > # of subs:%d\n", num, if_state.gpps->nsubs);
                    return (ERR_psi_Subr_too_hi);
                }
                psubrs = (PSUBS_STR)MEMptr (if_state.gpps->hsubrs);
                if (!psubrs[num].decrypted)
                {
                    estart (FSA (LPUB8)MEMptr (psubrs[num].hdata), psubrs[num].len);
                    psubrs[num].decrypted = TRUE;
                }
                edata = (LPUB8)MEMptr (psubrs[num].hdata) + if_state.gpps->lenIV;
                break;
            case t1_RETURN:  /* rets */
                DBG ("rets\n");
                edata = if_state.subcalls[--sublevel].data;
                if_state.gpps->psiw.code = if_state.subcalls[sublevel].key;
                
                break;
            case t1_ESCAPE:
                tmp = GETECHAR ();
                
                switch  (tmp)
                {
                case t1e_DOTSECTION: /* dotsection */
                    DBG ("dotsection\n");
                    break;
                case t1e_VSTEM3: /* vstem6 */
                    DBG ("vstem6\n");
                    
/*** modified version, to go with new vstem6() implementation ***/
/*** pass all args in original form (x's and dx's) ***/

                    FPOP(if_state.curve1[5]);
                    FPOP(poptmp);
                    if_state.curve1[4] = poptmp + sx;
                    FPOP(if_state.curve1[3]);
                    FPOP(poptmp);
                    if_state.curve1[2] = poptmp + sx;
                    FPOP(if_state.curve1[1]);
                    FPOP(poptmp);
                    if_state.curve1[0] = poptmp + sx;

                    status = vstem6 (FSA if_state.curve1);                   
                    if (status)
                        return (status);
                    
                    break;
                    
                case t1e_HSTEM3: /* hstem6 */
                    DBG ("hstem6\n");
                    FPOP(if_state.curve1[5]);
                    FPOP(poptmp);
                    if_state.curve1[4] = poptmp + sy;
                    FPOP(if_state.curve1[3]);
                    FPOP(poptmp);
                    if_state.curve1[2] = poptmp + sy;
                    FPOP(if_state.curve1[1]);
                    FPOP(poptmp);
                    if_state.curve1[0] = poptmp + sy;
                    
                    if_state.curve1[1] += if_state.curve1[0];
                    if_state.curve1[3] += if_state.curve1[2];
                    if_state.curve1[5] += if_state.curve1[4];
                    
                    status = hstem6 (FSA if_state.curve1);
                    if (status)
                        return (status);
                    
                    break;
                    
                case t1e_SEAC: /* composite-char */
                    DBG ("composite\n");
                    
                    /* 11-16-93 jfd
                    *
                    * Save 'cc2', 'cc1','deltay', 'deltax' and 'llx_accent'
                    * in a buffer in case we need them later for positioning
                    * a compound character part.
                    *
                    */
                    
                    FPOP(poptmp);
                    cc2 = cc2_buf[seacs_called] = (SL32)(poptmp & 0xffff);
                    FPOP(poptmp);
                    cc1 = cc1_buf[seacs_called] = (SL32)(poptmp & 0xffff);
                    FPOP(poptmp);
                    deltay = deltay_buf[seacs_called] = poptmp;
                    FPOP(poptmp);
                    deltax = deltax_buf[seacs_called] = poptmp;
                    FPOP(poptmp);
                    llx_accent = llx_accent_buf[seacs_called] = poptmp;
                    
                    /* 11-16-93 jfd
                    *
                    * Save 'llx' associated with this SEAC.
                    *
                    */
                    
                    llx_buf[seacs_called] = llx;
                    
                    /* 11-16-93 jfd
                    *
                    * Keep count of compound character parts being processed.
                    *
                    */
                    
                    ccparts_needed += 2;
                    
                    
                    /* 11-16-93 jfd
                    *
                    * If any points have been processed prior to a SEAC command,
                    * throw them away,
                    */
                    
                    if (if_state.gpcs->ct_lineto || if_state.gpcs->ct_quadto || if_state.gpcs->ct_cubeto)
                        status = t1startchar (FSA sx, sy, xadv);
                    
                        /* 11-16-93 jfd
                        *
                        * Keep count of SEAC commands processed.
                        *
                    */
                    
                    seacs_called++;
                    
                    composite = TRUE;
                    donecc2 = FALSE;
                    
                    if_state.gpps->psiw.curx = sx = llx;
                    if_state.gpps->psiw.cury = sy = 0;
                    
                    /* If closepath has not been executed for prevvious loop,
                    * we will do it ourselves here!
                    *
                    *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                    */
                    if (!closepath_called)
                    {
                        savex = if_state.gpps->psiw.curx;
                        savey = if_state.gpps->psiw.cury;
                        status = t1closepath(FSA0);
                        if (status)
                            return (status);
                    }
                    else
                        closepath_called = 0;
                    
                    status = MOVETO (sx, sy);
                    if (status)
                        return (status);
                    
                    /* do cc1 here, cc2 is done at endchar  */
                    
                    DBG1 ("Begin character decoding for comp char %d\n", cc1);
                    
#if PST1_SFNTI
                    /*
                    NOTE:
                    The following code is to support generic downloaded soft fonts.
                    It is up to the application to provide a call back loader to handle
                    them. During DEBUG, we will assume that they look like PSEO's.
                    */
                    if (PCLflag)
                    {
                        ph = PCLchId2ptr (FSA cc1);
                        if (!ph)
                        {
                            DBG1 ("type1char() - can't find PCLEO compound char 1:%d\n",
                                cc1);
                            return (ERR_psi_cc_missing);
                        }
                        ph += sizeof (PS_CHAR_HDR); /* -> Namelen */
                        UNPACK_WORD((LPUB8)&Namelen);   /* get Namelen */
                        UNPACK_WORD((LPUB8)&Datalen);   /* get Datalen */
                        ph += Namelen;           /* -> Data */
                        Decryptflag = *(ph + Datalen); /* get Decrypt byte */
                        if (!Decryptflag) /* only handle decrypted data for now */
                            return (ERR_psi_pcleo_encr);
                        pdata = ph;
                    }
                    else
#endif /* PST1_SFNTI */
                        {
#if PS_RESIDENT
                            
                            cptr = finddata (FSA cc1);  /* get 1st part of compound char */
                            if (!cptr)
                                return (ERR_psi_cc_missing);
                            pdata = (LPUB8)MEMptr (cptr->hdata); /* add 1/3/92 - rs */
                            
                            if (!cptr->decrypted)
                            {
                                estart (FSA pdata, cptr->len);
                                cptr->decrypted = TRUE;
                            }
#endif    /* PS_RESIDENT */
                        } /* else not PCLEO */
                        
                        ccparts_processed++;  /* 11-16-93 jfd */
                        
                        edata = pdata + if_state.gpps->lenIV;
                        break;
                        
          case t1e_SBW: /* set x,y sidebearing and width */
              DBG ("sbw: ");
            /* Still need to pop the y value off the stack but we don't care what */
            /* the value is. */
                FPOPX();
              if (!composite)
              {
                  FPOP(xadv);
                  DBG1 ("xadv = %ld, ", xadv);
                  
                  FPOP(poptmp);
                  if_state.gpps->psiw.cury = sy = poptmp;
                  FPOP(poptmp);
                  if_state.gpps->psiw.curx = llx = sx = poptmp;
                  DBG2 ("if_state.gpps->psiw.curx = %ld, if_state.gpps->psiw.cury = %ld",
                      if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                  
                  status = t1startchar (FSA sx, sy, xadv);
                  
                  /* Set flag indicating whether  closepath() was called
                  * for previous loop to 1 since this is the start of 
                  * the character and there is no previous loop. This
                  * is being done so that when MOVETO is processed,
                  * closepath() will not be called by us.
                  *
                  * 10-13-93 jfd
                  */
                  
                  closepath_called = 1;  
                  
                  if (status || wflag)
                      return (status);
                  /* moveto (sx, sy); */
              }
              else if (!donecc2)
              {
                  FPOPX ();
                   FPOP(poptmp);
                   if_state.gpps->psiw.curx = sx = poptmp;
                  
                  /* If closepath has not been executed for prevvious loop,
                  * we will do it ourselves here!
                  *
                  *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                  */
                  if (!closepath_called)
                  {
                      savex = if_state.gpps->psiw.curx;
                      savey = if_state.gpps->psiw.cury;
                      status = t1closepath(FSA0);
                      if (status)
                          return (status);
                  }
                  else
                      closepath_called = 0;
                  
                  status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
                  if (status)
                      return (status);
              }
              else
              {
                  FPOPX ();
                  FPOPX ();
              }
              DBG ("\n");
              
              break;
              
          case t1e_DIV: /* div */
                /*
                ** This is the only place that I see the
                ** need for floating point, and it only appears
                ** to be used for the hints.  We'll do the divide
                ** at a higher precision, round the result, and
                ** convert it back to an integer.  There seems to
                ** no loss of detail when this is done
                */
              
              DBG ("div\n");
              FPOP(x2);
              FPOP(x1);
              /* compute in 16ths, round, and put back */
              FPUSH (T1ROUND ((((SL32) x1) << 4) / x2) >> 4);
              break;
              
          case t1e_CALLOTHERSUBR: 
              /* OtherSubrs calls -- In a PostScript interpreter,
                 this would end up executing a PostScript procedure
                 indexed by "num" inside  OtherSubrs,
                 (which is an array of procs stored inside the font's
                 Private dictionary)
              */
              
              FPOP(poptmp);
              num = (SW16)(poptmp & 0xffff);
              FPOP(arg); /* number of args to push onto the PostScript stack */
              
              DBG1 ("OtherSubr %d\n", num);
              status = othersubr (FSA num, arg);
              if(status)
                  return status;
              break;
              
          case t1e_POP: /* push-result */
              DBG ("push result\n");
              /* In a PostScript interpreter, this means to pop the top
              of the PostScript stack and push it onto the internal stack */
              break;
              
          case 0x20: /* push-curr-pt */
              DBG ("push-curr-pt!\n");
              /* In a PostScript interpreter, this means to push the current internal
              point onto the PostScript stack */
              break;
              
          case t1e_SETCURPT: /* Fmoveto */
              DBG ("Fmoveto\n");
              /* In a PostScript interpreter, this means to set the current
              point to the two values popped off the internal stack */
              
              /* Added these lines to fix placement 
              of accents on compound characters of "special" Type 1 fonts
              - 10/15/93 - jfd
              */
              FPOP(if_state.gpps->psiw.cury);
              FPOP(if_state.gpps->psiw.curx);
              break;
        } /* switch (tmp) - ESCAPE commands */
        break;
        
      case t1_HSBW:  /* offset width charwidth */
          DBG ("start char\n");
          if (!composite)
          {
              FPOP(xadv);
              
              FPOP(poptmp);
              if_state.gpps->psiw.curx = llx = sx = poptmp;
              if_state.gpps->psiw.cury = sy = 0;
              
              status = t1startchar (FSA sx, sy, xadv);
              
              /* Set flag indicating whether  closepath() was called
              * for previous loop to 1 since this is the start of 
              * the character and there is no previous loop. This
              * is being done so that when MOVETO is processed,
              * closepath() will not be called by us.
              *
              * 10-13-93 jfd
              */
              
              closepath_called = 1;  
              
              if (status || wflag)
                  return (status);
          }
          else if (!donecc2)
          {
              FPOPX ();
              FPOP(poptmp);
              if_state.gpps->psiw.curx = sx = poptmp;
              
              llx = if_state.gpps->psiw.curx;  /* 11-16-93 jfd */

                /* If closepath has not been executed for prevvious loop,
                * we will do it ourselves here!
                *
                *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                */
              
              if (!closepath_called)
              {
                  savex = if_state.gpps->psiw.curx;
                  savey = if_state.gpps->psiw.cury;
                  status = t1closepath(FSA0);
                  if (status)
                      return (status);
              }
              else
                  closepath_called = 0;
              
              status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
              if (status)
                  return (status);
          }
          else
          {
              FPOPX ();
              FPOP(poptmp);
              if_state.gpps->psiw.curx += poptmp;
              sx = if_state.gpps->psiw.curx;
          }
          
          break;
          
      case t1_ENDCHAR: /* endchar */
          DBG ("end char\n");
          
          /* 11-16-93 jfd
          *
          * Check for multiple SEACs so as not to stop processing
          * prematurely.
          *
          */
          
          if (composite && (!donecc2 || (seacs_called > 1)) )
          {
              /* end cc1, now do cc2 */
              
              /* 11-16-93 jfd
              *
              * If multiple SEACs, use correct displacements.
              *
              */
              
              ccparts_processed++;
              if (ccparts_processed >= ccparts_needed)
              {
                  seacs_called--;
                  
                  if (seacs_called)
                  {
                      deltax = deltax_buf[seacs_called-1];
                      llx_accent = llx_accent_buf[seacs_called-1];
                      llx = llx_buf[seacs_called-1];
                  }
                  else
                      llx = llx_buf[0];
                  
              }
              
              /* 11-16-93 jfd
              *
              * Set 'if_state.psiw.curx' using accent origin 'deltax' and left side bearing.
              *
              */
              
              if_state.gpps->psiw.curx = sx = (llx + deltax) - llx_accent;
              if_state.gpps->psiw.cury = sy = deltay;
              
              /* If closepath has not been executed for prevvious loop,
              * we will do it ourselves here!
              *
              *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
              */
              
              if (!closepath_called)
              {
                  savex = if_state.gpps->psiw.curx;
                  savey = if_state.gpps->psiw.cury;
                  status = t1closepath(FSA0);
                  if (status)
                      return (status);
              }
              else
                  closepath_called = 0;
              
              status = MOVETO (sx, sy);
              if (status)
                  return (status);
              
              DBG1 ("Rendering composite char %d\n", cc2);
              /* Note: in an interpreter environment, look up cc2 based
              upon the standard encoding for the font, not based upon
              the current Encoding array (the font may have been
              reencoded) */
              
#if PST1_SFNTI
              /*
              NOTE:
              The following code is to support generic downloaded soft fonts.
              It is up to the application to provide a call back loader to handle
              them. During DEBUG, we will assume that they look like PSEO's.
              */
              if (PCLflag)
              {
                  ph = PCLchId2ptr (FSA cc2);
                  if (!ph)
                  {
                      DBG1 ("type1char() - can't find PCLEO compound char 2:%d\n",
                          cc2);
                      return (ERR_psi_cc_missing);
                  }
                  ph += sizeof (PS_CHAR_HDR); /* -> Namelen */
                  UNPACK_WORD((LPUB8)&Namelen);   /* get Namelen */
                  UNPACK_WORD((LPUB8)&Datalen);   /* get Datalen */
                  ph += Namelen;           /* -> Data */
                  Decryptflag = *(ph + Datalen); /* get Decrypt byte */
                  if (!Decryptflag) /* only handle decrypted data for now */
                      return (ERR_psi_pcleo_encr);
                  pdata = ph;
              }
              else 
#endif /* PST1_SFNTI */
                  {
#if PS_RESIDENT
                      
                      cptr = finddata (FSA cc2); /* get 2nd part of compound char */
                      if (!cptr)
                          return (ERR_psi_cc_missing);
                      
                      pdata = (LPUB8)MEMptr (cptr->hdata);  /* add 1/3/92 - rs */
                      if (!cptr->decrypted)
                      {
                          estart (FSA pdata, cptr->len);
                          cptr->decrypted = TRUE;
                      }
#endif    /* PS_RESIDENT */
                  } /* else not PCLEO compound char */
                  
                  edata = pdata + if_state.gpps->lenIV;
                  donecc2 = TRUE;
        }
        else
            /* we're done here; exit the processing loop */
            goto EXITLOOP;
        
        break;
        
      case 0x0f:  /* moveto */
          FPOP(if_state.gpps->psiw.cury);
          FPOP(if_state.gpps->psiw.curx);
          DBG2 ("moveto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          
          /* If closepath has not been executed for prevvious loop,
          * we will do it ourselves here!
          *
          *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          */
          
          if (!if_state.record)  /* 10-25-93 jfd */
          {
              
              if (!closepath_called)
              {
                  savex = if_state.gpps->psiw.curx;
                  savey = if_state.gpps->psiw.cury;
                  status = t1closepath(FSA0);
                  if (status)
                      return (status);
              }
              else
                  closepath_called = 0;
              
          }  /* 10-25-93 jfd */
          
          if (!if_state.record)
              status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          if (status)
              return (status);
          break;
          
      case 0x10:  /* lineto */
          FPOP(if_state.gpps->psiw.cury);
          FPOP(if_state.gpps->psiw.curx);
          DBG2 ("lineto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          status = LINETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          if (status)
              return (status);
          break;
          
      case 0x11:  /* curveto */
          DBG ("curveto\n");
          FPOP(y3);
          FPOP(x3);
          FPOP(y2);
          FPOP(x2);
          FPOP(y1);
          FPOP(x1);
          
          DBG6 ("curveto %ld %ld %ld %ld %ld %ld\n",
              x1, y1, x2, y2, x3, y3);
          status = CURVETO (x1, y1, x2, y2, x3, y3);
          if (status)
              return (status);
          
          if_state.gpps->psiw.curx = x3;
          if_state.gpps->psiw.cury = y3;
          break;
          
      case t1_RMOVETO:  /* rmoveto */
          FPOP(poptmp);
          if_state.gpps->psiw.cury += poptmp;
          FPOP(poptmp);
          if_state.gpps->psiw.curx += poptmp;
          DBG2 ("rmoveto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          
          /* If closepath has not been executed for prevvious loop,
          * we will do it ourselves here!
          *
          *  10-13-93 jfd 
          */
          
          if (!if_state.record)  /* 10-25-93 jfd */
          {
              
              if (!closepath_called)
              {
                  savex = if_state.gpps->psiw.curx;
                  savey = if_state.gpps->psiw.cury;
                  status = t1closepath(FSA0);
                  if (status)
                      return (status);
              }
              else
                  closepath_called = 0;
              
          } /* 10-25-93 jfd */
          
          if (!if_state.record)
          {
              status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
              if (status)
                  return (status);
          }
          break;
          
      case t1_HMOVETO:  /* xrmoveto */
          FPOP(poptmp);
          if_state.gpps->psiw.curx += poptmp;
          DBG2 ("xrmoveto %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
          
          /* If closepath has not been executed for prevvious loop,
          * we will do it ourselves here!
          *
          *  10-13-93 jfd !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          */
          
          if (!if_state.record)  /* 10-25-93 jfd */
          {
              
              if (!closepath_called)
              {
                  savex = if_state.gpps->psiw.curx;
                  savey = if_state.gpps->psiw.cury;
                  status = t1closepath(FSA0);
                  if (status)
                      return (status);
              }
              else
                  closepath_called = 0;
              
          }  /* 10-25-93 jfd */
          
          if (!if_state.record)
          {
              status = MOVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury);
              if (status)
                  return (status);
          }
          break;
          
      case t1_VHCURVETO:  /* yrcurveto */
          DBG ("yrcurveto\n");
          FPOP(x2);
          FPOP(y2);
          FPOP(x1);
          FPOP(y1);
          DBG6 ("yrcurveto %ld %ld %ld %ld %ld %ld\n", if_state.gpps->psiw.curx, if_state.gpps->psiw.cury+y1,
              if_state.gpps->psiw.curx+x1, if_state.gpps->psiw.cury+y1+y2, if_state.gpps->psiw.curx+x1+x2, if_state.gpps->psiw.cury+y1+y2);
          
          status = CURVETO (if_state.gpps->psiw.curx, if_state.gpps->psiw.cury + y1, if_state.gpps->psiw.curx + x1, if_state.gpps->psiw.cury + y1 + y2,
              if_state.gpps->psiw.curx + x1 + x2, if_state.gpps->psiw.cury + y1 + y2);
          if (status)
              return (status);
          
          if_state.gpps->psiw.curx += x1 + x2;
          if_state.gpps->psiw.cury += y1 + y2;
          break;
          
      case t1_HVCURVETO:  /* xrcurveto */
          DBG ("xrcurveto\n");
          FPOP(y2);
          FPOP(y1);
          FPOP(x2);
          FPOP(x1);
          DBG6 ("xrcurveto %ld %ld %ld %ld %ld %ld\n", if_state.gpps->psiw.curx+x1, if_state.gpps->psiw.cury,
              if_state.gpps->psiw.curx+x1+x2, if_state.gpps->psiw.cury+y1, if_state.gpps->psiw.curx+x1+x2, if_state.gpps->psiw.cury+y1+y2);
          
          status = CURVETO (if_state.gpps->psiw.curx + x1, if_state.gpps->psiw.cury, if_state.gpps->psiw.curx + x1 + x2, if_state.gpps->psiw.cury + y1,
              if_state.gpps->psiw.curx + x1 + x2, if_state.gpps->psiw.cury + y1 + y2);
          if (status)
              return (status);
          
          if_state.gpps->psiw.curx += x1 + x2;
          if_state.gpps->psiw.cury += y1 + y2;
          break;
          
      default:
          DBG1 ("%%%%%% Unknown opcode 0x%x %%%%%%\n", c & 0xffff);
          return (ERR_psi_rdfont);
    } /* switch ((SW16)(c & 0xffff)) */
  }
  
EXITLOOP:
  
  /* vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */
  
  /* 10-13-93 jfd   
  * If CLOSEPATH has not been called, call it here!
  */
  
  if (!closepath_called)
  {
      savex = if_state.gpps->psiw.curx;
      savey = if_state.gpps->psiw.cury;
      status = t1closepath(FSA0);
      if (status)
          return (status);
      status = MOVETO (savex, savey);
      if (status)
          return (status);
  }
  
  /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
  
  status = ENDCHAR ();
  if (status)
      return (status);
  
  DBG ("type1char - done rendering character\n"); 
  return (SUCCESS);
}

#if T1MMASTER
#define blendround(a)   (((a) + (1 << 15)) >> 16)

#if defined (ANSI_DEFS)
MLOCAL SL32 blend (FSP LPSL32 x)
#else
MLOCAL SL32 blend (x)
LPSL32 x;
#endif
{
    register SL32  result = 0;
    SL32     i;
    
    DBG1 ("blend (%ld", x[0]);
    
    for  (i = 1; i < if_state.gpps->Weightvals; ++i)
    {
        result += x[i] * if_state.gpps->weights[if_state.gpps->Weightvals - i];
        DBG1 (" %ld", x[i]);
    }
    
    result = blendround (result + (x[0] << 16));
    
    DBG1 (") = %ld\n", result);
    
    return (result);
}
#endif /* T1MMASTER */

#if defined (ANSI_DEFS)
MLOCAL UW16 othersubr (FSP SL32 num, SL32 arg)
#else
MLOCAL UW16 othersubr (num, arg)
SL32   num;
SL32  arg;
#endif
/*
num = subroutine number
arg = number of args to push onto the PostScript stack 
*/
{
    SL32   i;
    SL32  dmin;
    SL32   status;
    
#if T1MMASTER
    SL32 bargs[128], blends[128];
    SL32 firstarg, blendn, j, k;
#endif
    
    /* OtherSubrs calls -- In a PostScript interpreter,
    this would end up executing a PostScript procedure
    indexed by "num" inside  OtherSubrs,
    (which is an array of procs stored inside the font's
    Private dictionary)
    */
    
    
    DBG1 ("OtherSubr %d\n", num);
    
    switch (num)
    {
    case 0x00: /* FlxProc */
        if_state.record = FALSE;
        FPOP(if_state.gpps->psiw.ey);
        FPOP(if_state.gpps->psiw.ex);
        FPOP(dmin);
        FPOP(if_state.curve2[5]);
        FPOP(if_state.curve2[4]);
        FPOP(if_state.curve2[3]);
        FPOP(if_state.curve2[2]);
        FPOP(if_state.curve2[1]);
        FPOP(if_state.curve2[0]);
        FPOP(if_state.curve1[5]);
        FPOP(if_state.curve1[4]);
        FPOP(if_state.curve1[3]);
        FPOP(if_state.curve1[2]);
        FPOP(if_state.curve1[1]);
        FPOP(if_state.curve1[0]);
        FPOP(if_state.gpps->psiw.y);
        FPOP(if_state.gpps->psiw.x);
        
        status = flexproc (FSA if_state.gpps->psiw.epx, if_state.gpps->psiw.epy, if_state.curve1, if_state.curve2, dmin);
        if (status)
            return (status);
        
            /* TRY PUSHING if_state.psiw.ex and if_state.psiw.ey ONTO STACK FOR LATER USE BY t1e_SETCURPT 
            *  10-22-93 jfd 
        */
        /*            if_state.psiw.curx = if_state.psiw.ex; */
        /*            if_state.psiw.cury = if_state.psiw.ey; */
        /* 10-16-96 jfd
        * Push current x and y onto stack to fix accent rendering and
        * placement problem.
        */
        if_state.gpps->psiw.ex = if_state.gpps->psiw.curx;
        if_state.gpps->psiw.ey = if_state.gpps->psiw.cury;
        FPUSH (if_state.gpps->psiw.ex); /* 10-22-93 jfd */
        FPUSH (if_state.gpps->psiw.ey); /* 10-22-93 jfd */
        break;
        
    case 0x01: /* begin-record */
        if_state.record = TRUE;
        if_state.gpps->psiw.epx = if_state.gpps->psiw.curx;
        if_state.gpps->psiw.epy = if_state.gpps->psiw.cury;
        break;
        
    case 0x02: /* Push current point */
        FPUSH (if_state.gpps->psiw.curx);
        FPUSH (if_state.gpps->psiw.cury);
        break;
        
    case 0x03: /* strlck or startlock */
        /* leave subr number on the stack */
        for (i = 0; i < (SW16)(arg & 0xffff) - 1; ++i)
            FPOPX ();
        
        break;
        
#if T1MMASTER
    case 14:  /* returns 1 blended value */
    case 15:  /*    "    2    "      "   */
    case 16:  /*    "    3    "      "   */
    case 17:  /*    "    4    "      "   */
    case 18:  /*    "    6    "      "   */
        blendn = num - 13; 
        if(blendn == 5)
            blendn++;
        
        for (i = blendn, k = 0; i > 0; --i, ++k)
        {
        /* there are blendn sets of (Weightvals - 1) args on 
            the stack, the first args are after all these  */
            
            firstarg = i * (if_state.gpps->Weightvals - 1) + k;
            
            bargs[0] = *(if_state.argsptr - firstarg - 1);
            
            for (j = 1; j < if_state.gpps->Weightvals; ++j) 
                FPOP(bargs[j]);
            
            blends[i] = blend (FSA bargs);
        }
        
        for (i = 0; i < blendn; ++i)
            FPOPX ();
        
        for (i = 0; i < blendn; ++i)
            FPUSH (blends[i + 1]);
        
        break;
#endif /* T1MMASTER */
        
    default:
        for (i = 0; i < (SW16)(arg & 0xffff); ++i)
            FPOPX ();
        break;
    }
    
    return (SUCCESS);
}


#if defined (ANSI_DEFS)
GLOBAL UW16 psset_char (FSP PBUCKET pxb, UL32 chId)
#else
GLOBAL UW16 psset_char (pxb, chId)
PBUCKET  pxb;
UL32      chId;
#endif
/*
NOTE: This scheme depends upon memory not moving between this call to
'set_char()' and the followup call to 'make_gaso...()'.

  03/20/92 - rs - Add support for PostScript PCLEO
*/
{
#if PST1_DISK || PST1_RAM
    LPSB8       char_name;
    PCDATASTR   cptr, cend;
#endif

    register PPS_BUCK    pps;
    SL32       status = 0;  
    
    if_state.gpxb = pxb;
    if_state.gpps = pps = &pxb->p.ps;
    
    if (if_state.gpps->hexascii == CFF)    /* only set if a cff font is detected */
    {
#if CFF_RDR
        return Cff_Set_Char(FSA (UW16)chId);    /* rjl 9/24/2002 - added (UW16) cast*/
#else
        return ERR_cff_not_enabled;
#endif
    }

    /* if we get past this point, it is NOT a CFF font */
    DBG ("ps_set_char()\n");

#if PST1_SFNTI
    /*
    If this is an external (generic downloaded) soft font, have it
    loaded by the application's type 1 soft font loader.
    */
    
#if (ROM && PS_PLUGINS) || IF_PCLEOI
    /* make sure char_buf is pointing at the static buffer and not to a  */
    /* previous reference to a character in ROM (like a plugin.)         */
    /*                                            -ss,jfd,dbk 2/16/93    */
    
    if_state.char_buf = (LPSB8)MEMptr (if_state.hchar_buf);
#endif
    
    if (pxb->extern_font)
    {   /* PS type 1 downloaded soft font */
        pps->pthis_charstring = PCLchId2ptr (FSA (UW16)chId);   /* rjl 9/24/2002 - added (UW16) cast*/
        if (!pps->pthis_charstring)
        {
            DBG("Could not find PS PCLEO character data\n");
            return (ERR_psi_pcleo_nodata);
        }
        return (SUCCESS);
    }
#endif /* PST1_SFNTI */

    /* if we get past this point, it is NOT a CFF font and is NOT a soft font,
        so it MUST be a PST1_DISK or PST1_RAM font */

    /* First get the name of this character */


#if PST1_DISK || PST1_RAM

#if (USE_UFST_MAPPING == 2)
    if (pxb->cur_ssnum != T1ENCODING)
    {
#endif  /* USE_UFST_MAPPING == 2 */
                
#if USE_PS_SYMSET
        {
        VOID   *cgnum;
        UW16    cgnumidx;
        UW16    mapidx;

            if (FC_NO_SSMAP(&if_state.fcCur))
            {
                cgnum = if_state.PSchar_name;

                if (!cgnum)
                {
                    DBG1 ("Unable to get cgnum for chId %d\n", chId);
                    return (ERR_no_cgnum);
                }

                char_name = if_state.PSchar_name;
            }
            else
            {
                cgnumidx = SYMmap (FSA (SW16)chId, FC_PST1_TYPE);  /* rjl 9/24/2002 - added (UW16) cast*/

                if (!cgnumidx)
                {
                    DBG1 ("Unable to get cgnum for chId %d\n", chId);
                    return (ERR_no_cgnum);
                }

                mapidx = cm_cgidToIndex (cgnumidx);
                if (!mapidx)
                {
                    DBG1 ("Unable to get map index for cgnum %d\n", cgnumidx);
                    return (ERR_psi_cg2idx);
                }
                char_name = PSdata[mapidx];
                if (!char_name)
                {
                    DBG1 ("Unable to get PS name for map index %d\n", mapidx);
                    return (ERR_psi_idx2psname);
                }
            }
        }                
#endif  /* USE_PS_SYMSET */
                
#if (USE_UFST_MAPPING == 2)
    }
    else
    {
#endif  /* USE_UFST_MAPPING == 2 */
                
#if USE_PS_ARRAY
        {
        PMEM_HANDLE pencodearray;
                
            if (FC_NO_SSMAP(&if_state.fcCur))
            {                
                /* use mapping from PostScript font */
                if (pps->hencodearray)
                {
                    pencodearray = (PMEM_HANDLE)MEMptr (pps->hencodearray);
                    if (!pencodearray[chId])
                        char_name = NULL;
                    else char_name = (LPSB8)MEMptr (pencodearray[chId]);
                }
                else
                    char_name = stdencoding[chId];
            }
            else
            {
                char_name = if_state.PSchar_name;
                    
                /* use mapping from PostScript font */
                if (pps->hencodearray)
                {
                    SL32 i;
                    pencodearray = (PMEM_HANDLE)MEMptr (pps->hencodearray);
                    for (i=0; i<256; i++)
                    {
                        if (!STRCMP ((FILECHAR *)MEMptr (pencodearray[i]), char_name))
                        {
                            chId = i;
                            break;
                        }
                    }
                    if (i >= pps->n_chars)
                        char_name = NULL;
                }
                else
                    char_name = NULL;
            }                

            /* If this character is not defined in the symbol set, return an error */
            
            if (!char_name)
            {
                if_state.gpps = (NULL);
                return (ERR_no_cgnum);  /* char not in symbol set */
            }
        }
#endif /* USE_PS_ARRAY */
                
#if (USE_UFST_MAPPING == 2)
    }
#endif /* USE_UFST_MAPPING == 2 */
            
    /* Character is defined, search the charstrings and get a ptr to it */
            
    cend =(PCDATASTR)MEMptr (pps->hcharstrings) + pps->n_chars;
    for (cptr = (PCDATASTR)MEMptr (pps->hcharstrings); cptr < cend; ++cptr)
    {
          /* add 5/1/92 - 2 line fix for Sparc crash w/ext mem - rs */
        if (cptr->hname == NIL_MH)
            break;

        if (!STRCMP ((FILECHAR *)MEMptr (cptr->hname), char_name))
        {
            pps->pthis_charstring = cptr;
            if_state.gpps = (NULL);
            return (SUCCESS);
        }
    } /* for (cptr = ...) */
        
    /* Character is not in charstrings, see if it has not been loaded yet.. */
    if (pps->curr_char < pps->n_chars)
    {
        status = more_charstrings (FSA char_name);
        if_state.gpps = (NULL);
        return (status);
    }
    else
    {
        if_state.gpps = (NULL);
        return (ERR_no_cgnum);
    }
#endif    /*  PST1_DISK || PST1_RAM */ 

    return(status);     /* shouldn't reach this point... */

}


#if defined (ANSI_DEFS)
GLOBAL UW16 psmake_gaso_and_stats (FSP PBUCKET pxb, PCHAR_STATS pcs)
#else
GLOBAL UW16 psmake_gaso_and_stats (pxb, pcs)
PBUCKET     pxb;
PCHAR_STATS pcs;
#endif
{
    SL32 status;
    
    DBG ("psmake_gaso_and_stats()\n");
    
    if_state.gpxb = pxb;    /* ptr to XBUCKET */
    if_state.gpps = &pxb->p.ps;   /* ptr to PS specific info in bucket */
    if_state.gpcs = pcs;    /* ptr to CHAR_STATS */
    
#if 1    /* very special-purpose errorcheck to handle out-of-sequence psfunc_tbl[] calls */
    if (!if_state.gpps->transptr)
        return ERR_psi_generic;
#endif
    
    /* reset counters */
    if_state.gpcs->ct_lineto = if_state.gpcs->ct_quadto = if_state.gpcs->ct_cubeto = 0;
    
    if(if_state.gpps->CharstringType == 2)    /* CFF type2    */
#if CFF_RDR
        status = type2char(FSA if_state.gpps->pthis_charstring, 0);
#else
        status = ERR_cff_not_enabled;
#endif
    else                            /* PS Type1        */
    {
        status = type1char(FSA if_state.gpps->pthis_charstring, 0);
    }
    
    if(status)
        return status;
    
    if_state.gpps = (PPS_BUCK)0;
    if_state.gpcs = (PCHAR_STATS)0;
    return (status);
}

#if INTR_SIZE == 16
#define rs(v)    (INTR)((v) >> if_state.right_shift)
#else
#define rs(v)    (INTR)v
#endif

#if defined (ANSI_DEFS)
GLOBAL UW16 psrender ( FSP PVOID s, PBUCKET pxb, INTR xt, INTR yt)
#else
GLOBAL UW16 psrender (s, pxb, xt, yt)
PVOID s;
PBUCKET  pxb;
INTR xt, yt;
#endif
{
    INTR  c0x, c0y, c1x, c1y;
    INTR  px, py;
    LPSB8 p;
    LPSL32 cv;
    UW16 loopct, npnt;
#if defined (AGFADEBUG)
    UW16 nbez;
#endif
    UW16 polarity;
    
    SL32 status;
    
    DBG ("\npsrender()\n");
    /* Restore pointer to bucket */
    if_state.gpps = &pxb->p.ps;
    
    /* Make certain that output format is valid for PS */
    
#if !LINEAR
    if (if_state.cs.format == FC_LINEAR_TYPE)
        return ERR_linear_not_installed;
#endif
#if !CUBIC
    if (if_state.cs.format == FC_CUBIC_TYPE)
        return ERR_cubic_not_installed;
#endif
    if (if_state.cs.format == FC_QUAD_TYPE)
        return ERRinvalid_outproc_type;
    
    status = if_state.out.start_char (FSAvoid s, (PVOID)&if_state.cs);  /* 6-8-92 */
    if (status)
        return (status);
    
        /*
        Point to start of 1st loop
    */
    cv = (LPSL32)(if_state.char_buf);    /* XY coordinates */
#if (NAT_ALIGN == 8)
    p =
        (LPSB8)((((SL64)if_state.char_buf + CHARBUFSIZE) >> 1) << 1);
#else
    p =
        (LPSB8)((((SL32)if_state.char_buf + CHARBUFSIZE) >> 1) << 1);
#endif
    
    DBG1 ("%d loops\n", if_state.num_loops);
    for(loopct = 0; loopct < if_state.num_loops; loopct++)
    {
    /*
    Set up for next loop ->
    
      Type 1 input contains bezier data in character buffer.
      The XY coordinates begin at 'if_state.char_buf' and work
      upward. At the top of the buffer, (char_buf+CHARBUFSIZ-2),
      is the remainder of the data working downward. First, 'npnt'
      equals the number of vertex codes. This is followed by 'nbez'
      OR'd with the polarity. 'nbez' is the number of curves in the
      contour.
      Each curve has 1 SL32VECTOR accounted for in 'npnt' plus
      2 additional SL32VECTOR's accounted for in 'nbez'.
        */
        DBG("N e x t    L o o p\n");
        
#if (NAT_ALIGN == 8)
        p = (LPSB8)(((SL64)p >> 1) << 1);  /* align to SW16 boundary */
#else
        p = (LPSB8)(((SL32)p >> 1) << 1);  /* align to SW16 boundary */
#endif
        p -= sizeof(SW16);
        npnt     = *(LPSW16)p;        /* # of segments in this loop */
        p -= sizeof(SW16);
        polarity = (*(LPUW16)p & 0x8000) ? 1 : 0;
#if defined (AGFADEBUG)
        nbez = *(LPSW16)p & 0x7fff;   /* # of cubic beziers in this loop */
        DBG3 ("npnt:%d nbez:%d polarity:%d\n", npnt, nbez, polarity);
#endif
        p--;  /* point to 1st vertex code in loop */
        
        status = if_state.out.start_loop (FSAvoid s, polarity);
        if (status)
            return (status);
        
            /*
            Starting coord of loop
        */
        if_state.gpps->psiw.p0x = rs(*cv++ + xt);
        if_state.gpps->psiw.p0y = rs(*cv++ + yt);
#if INTR_SIZE == 16
        DBG2 ("moveto:%d %d\n", if_state.gpps->psiw.p0x, if_state.gpps->psiw.p0y);
#else
        DBG2 ("moveto:%ld %ld\n", if_state.gpps->psiw.p0x, if_state.gpps->psiw.p0y);
#endif
        status = if_state.out.moveto (FSAvoid s, if_state.gpps->psiw.p0x, if_state.gpps->psiw.p0y);
        if (status)
            return (status);
        
            /*
            Process each of the coords in this loop
        */
        while(npnt--)
        {
            if (!(*p--))        /* is this a cubic bezier? */
            {                          /*     yes    */
                DBG("vectorizing type 1 bezier\n");
                c0x = rs(*cv++ + xt);   /* 1st control point */
                c0y = rs(*cv++ + yt);
                c1x = rs(*cv++ + xt);   /* 2nd control point */
                c1y = rs(*cv++ + yt);
                px  = rs(*cv++ + xt);   /* end point */
                py  = rs(*cv++ + yt);
                /* Check for type of outline */
                
#if INTR_SIZE == 16
                DBG6 ("cubeto:%d %d %d %d %d %d\n", c0x, c0y, c1x, c1y, px, py);
#else
                DBG6 ("cubeto:%ld %ld %ld %ld %ld %ld\n", c0x, c0y, c1x, c1y, px, py);
#endif
                status = if_state.out.cubeto (FSAvoid s, c0x, c0y, c1x, c1y, px, py);
                if (status)
                    return (status);
                
                if_state.gpps->psiw.p0x = px;
                if_state.gpps->psiw.p0y = py;
                
            } /* if (*p--)) */
            else  /* LINETO */
            {
                px = rs(*cv++ + xt);  /* end point */
                py = rs(*cv++ + yt);
#if INTR_SIZE == 16
                DBG2 ("lineto:%d %d\n", px, py);
#else
                DBG2 ("lineto:%ld %ld\n", px, py);
#endif
                status = if_state.out.lineto (FSAvoid s, px, py);
                if (status)
                    return (status);
                if_state.gpps->psiw.p0x = px;
                if_state.gpps->psiw.p0y = py;
            }
        } /*  while(npnt--) */
        if_state.out.end_loop ( FSAvoid s );
    } /* for(loopct = 0;...) end of a loop */
    
      /*
      End of character
    */
    pxb=pxb;/*nop*/
    return if_state.out.end_char ( FSAvoid s );
}

#if WIDTHS
#if defined (ANSI_DEFS)
GLOBAL UW16 psget_width (FSP PBUCKET pbuck)
#else
GLOBAL UW16 psget_width (pbuck)
PBUCKET pbuck;
#endif
/*
Get width (escapement) of a type 1 character

  return (width) if no error, else (0)
*/
{
    SL32 status;
    UW16 width;


    /*
    Set up global PostScript pointers for use by lower level functions
    */
    if_state.gpxb = pbuck;    /* ptr to XBUCKET */
    if_state.gpps = &pbuck->p.ps;   /* ptr to PS specific info in bucket */
    if_state.gpcs = &if_state.cs;    /* ptr to CHAR_STATS */
    

    
    if(if_state.gpps->CharstringType == 2)    /* CFF type2    */
#if CFF_RDR
        status = type2char(FSA if_state.gpps->pthis_charstring, 1);
#else
        status = ERR_cff_not_enabled;
#endif
    else                            /* PS Type1        */
        status = type1char(FSA if_state.gpps->pthis_charstring, 1);
    
 
       width = (UW16)if_state.gpcs->escapement;
    
#if !DU_ESCAPEMENT
    /* Compensate for rounding when PS or TT is converted to 8782-based
    Multiply by TT or PS point size / Inteliifont point size
    = (1/72) / 0.01383 = 100,000/(72 * 1383)
    = 12500 / (9 * 1383) = 12500 / 12447     -ss,awr 8/20/92
    */
    if( pbuck->fst_type == FC_PST1_TYPE )    /* changed 'if_state.pbucket' to 'pbuck'  05-23-01 jfd */
    {
        width       = (UW16)( (((SL32)width * 12500L) + 6223L) / 12447L );
        if_state.gpcs->escapement = width;
    }
#endif  /* !DU_ESCAPEMENT */
    
    /*
    Clear global PostScript pointers for error control
    */
    if_state.gpps = (PPS_BUCK)0;
    if_state.gpcs = (PCHAR_STATS)0;
    
    if (status)
        return 0;  /* error */
    else
        return (width);
}
#endif /* WIDTHS */

#endif /* PST1_RDR */
 

  • 16
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值