T168_111\appl\Text\Agfa:第19文件

cgif.c    、/

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

/* $Header:   I:/BULL/URIP/RTS/DEP/CGIF.C_V   1.324   Jan 03 2005 14:48:38   DugganJ  $ */
/* $Log:   I:/BULL/URIP/RTS/DEP/CGIF.C_V  $ 
 * 
 *    Rev 1.324   Jan 03 2005 14:48:38   DugganJ
 * In CGIFFtt_query_direct(), if processing an ACT font,
 * decompress table before returning buffer.
 * 
 *    Rev 1.323   Dec 22 2004 16:20:46   galejss
 * change version string to "UFST 4.7"
 * 
 *    Rev 1.322   Dec 21 2004 11:18:48   galejss
 * add CR to end of file (fix compile on SUN)
 * 
 *    Rev 1.321   Dec 14 2004 16:15:16   dugganj
 * Renamed CGIFchar_map() to CGIFFchar_map()
 * for multithreading purposes.
 * 
 *    Rev 1.320   Dec 14 2004 15:47:36   galejss
 * make all DBG calls 16-bit-compatible
 * 
 *    Rev 1.319   Dec 14 2004 11:06:02   wuq
 * Fix bug #161.
 * Added carriage return at the end of the file.
 * 
 *    Rev 1.318   Dec 01 2004 17:34:54   galejss
 * change version string to "beta"
 * 
 *    Rev 1.317   Nov 29 2004 13:34:28   galejss
 * fix compile error (for IFBITSPLIT w/ reentrant processing)
 * 
 *    Rev 1.316   Nov 24 2004 17:24:52   galejss
 * fix build error caused by PVCS comment (believe it or not)
 * 
 *    Rev 1.315   Nov 17 2004 13:03:48   indreliunaiter
 * The  #endif-TT_RDR moved to the end of the CGIF.C file to fix the compilation issue when TT_RDR is disabled.
 * 
 *    Rev 1.314   Nov 15 2004 10:23:38   azimaf
 * 
 *    Rev 1.313   Nov 03 2004 10:06:38   DugganJ
 * In init_former_globals(), initialized new multithreading
 * fields that were added to IF_STATE.
 * 
 *    Rev 1.312   Oct 26 2004 11:35:28   dugganj
 * Multithreading changes.
 * 
 *    Rev 1.311   Oct 25 2004 17:42:06   galejss
 * add CGIFFget_kern_value(); fix a couple of compile issues
 * 
 *    Rev 1.310   Oct 07 2004 14:55:04   dugganj
 * Corrected incorrect delimiter at end of line (":" instead of ";")
 * 
 * 
 *    Rev 1.309   Oct 04 2004 18:46:52   galejss
 * allow CGIFmem_purge() to build if CACHE is disabled
 * 
 *    Rev 1.308   Oct 04 2004 14:58:12   dugganj
 * In CGIFFchar(), corrected error checking which was causing
 * incorrect return from function.
 * 
 *    Rev 1.307   Oct 01 2004 14:43:08   azimaf
 * added function CGIFmem_purge to
 * handle purging the BUFFER and CACHE pool
 * 
 *    Rev 1.306   Oct 01 2004 08:29:56   dugganj
 * In CGIFFfont(), before calling SYMnew(), test that 
 * "fc->ssnum != DL_SYMSET" to resolve error 54 bug.
 * 
 *    Rev 1.305   Sep 30 2004 18:29:34   galejss
 * fix do_banding() for non-ANSI_DEFS build; remove unused function normalize_n()
 * 
 *    Rev 1.304   Sep 27 2004 16:13:16   dugganj
 * Added multithread support.
 * 
 *    Rev 1.303   Sep 27 2004 09:05:46   wuq
 * Modified function check_types().
 * 
 *    Rev 1.302   Sep 24 2004 16:15:28   galejss
 * add carriage return to last line (needed for SUN compilation)
 * 
 *    Rev 1.301   22 Sep 2004 16:56:34   flewellinga
 * Updated version string to reflect 4.7 alpha
 * 
 *    Rev 1.300   Sep 20 2004 14:08:02   galejss
 * call initi_pcleo_callback_data(0 to initialize global data used by sample PCLEO code
 * 
 *    Rev 1.299   Sep 10 2004 11:23:12   wuq
 * Function for checking basic typedef added and called in CGIFinit(). 
 * 
 *    Rev 1.298   Aug 31 2004 11:25:32   azimaf
 * Added API support for WTLE
 * 
 *    Rev 1.297   Aug 19 2004 12:41:26   galejss
 * extract banding logic from CGIFchar() into new function do_banding();
 * make sure that banding is not applied for outline output
 * 
 *    Rev 1.296   Aug 10 2004 17:55:14   galejss
 * remove some commented-out code
 * 
 *    Rev 1.295   Aug 10 2004 17:51:28   galejss
 * changes for runtime no-symset-mapping (including WIDTH_NOSYMMAP define to enable alternate version of CGIFwidth)
 * 
 *    Rev 1.294   Jul 16 2004 13:34:40   galejss
 * changes for extended disk/rom support; BOOLEAN type cleanup
 * 
 *    Rev 1.293   Jun 04 2004 17:41:06   GalejsS
 * fix sign mismatches on status return values (compiler fixes)
 * 
 *    Rev 1.292   Apr 26 2004 18:01:06   GalejsS
 * changes for IFBITSPLIT; compiler warnings; return lower-level error code from CGIFfont_metrics()
 * 
 *    Rev 1.291   Nov 19 2003 12:16:04   Galejs
 * change version string to "" (for final release)
 * 
 *    Rev 1.290   Nov 07 2003 16:21:34   Galejs
 * CGIFwidth input charcode should be 32-bit value
 * 
 *    Rev 1.289   Nov 07 2003 12:11:42   Galejs
 * change versionstring to "release candidate"
 * 
 *    Rev 1.288   Oct 23 2003 10:53:58   Joe
 * Replaced constant "56" with symbol PCL_UNBOUND_FONT_SS.
 * 
 *    Rev 1.287   Oct 22 2003 15:44:36   Joe
 * Additional changes to CGIFfont() for correct processing of
 * IF unbound pcleos.
 * Removed some of the disabled code.
 * 
 *    Rev 1.286   Oct 17 2003 16:18:26   Joe
 * In CGIFfont(), fixed conditional compiler error.
 * In same function, changed the way "usePlugins" and
 * "useMapping" are calculated (by jfd and jwd).
 * 
 *    Rev 1.285   Oct 17 2003 14:46:58   Galejs
 * compile-warning fix in PSEUDO_HALF_WIDTH code
 * 
 *    Rev 1.284   Oct 09 2003 14:18:18   LynchR
 * Added check before MEMCMP of fc->font_hdr.
 * 
 *    Rev 1.283   Oct 06 2003 10:03:54   Al
 * CGIFfont() sets linked font to first member
 * 
 *    Rev 1.282   Sep 25 2003 16:58:16   Galejs
 * clean up comment
 * 
 *    Rev 1.281   Sep 25 2003 16:51:12   Galejs
 * add PS_ERRORCHECK stacklimit initialization; change versionstring to "beta"
 * 
 *    Rev 1.280   Sep 25 2003 14:01:14   Joe
 * Replaced "memcpy" with "MEMCPY".
 * 
 *    Rev 1.279   Sep 23 2003 09:34:28   Joe
 * In CGIFfont(), moved test for linked fonts before test for Intellifont to resolve
 * error when processing linked fonts with Intellifont disabled.
 * 
 *    Rev 1.278   Sep 19 2003 14:22:20   Joe
 * Moved test for chId > 0xffff from CGIFchar(), CGIFchar_handle() and CGIFchar_size()
 * to MAKifbmheader() so that linked fonts will process correctly.
 * 
 *    Rev 1.277   Aug 26 2003 13:06:40   Joe
 * Corrected syntax errors in CGIFfont() and CGIFchar().
 * 
 *    Rev 1.276   Aug 26 2003 10:50:10   Joe
 * In CGIFfont(), added fix for unbound pcleos.
 * 
 *    Rev 1.275   Aug 22 2003 08:57:08   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.274   Aug 21 2003 14:28:32   IndrelR
 *    Rev 1.273   Aug 21 2003 14:14:02   IndrelR
 * Added feature for processing XL bitmaps.
 * 
 *    Rev 1.272   Aug 21 2003 13:59:26   IndrelR
 * Added feature for processing XL bitmaps.
 * 
 *    Rev 1.271   Aug 20 2003 13:44:02   Joe
 * Left out some cleanup code in CGIFtt_query_direct_free(),
 * 
 *    Rev 1.270   Aug 19 2003 13:16:52   Joe
 * Added "table-by-reference" support.
 * 
 *    Rev 1.269   Aug 14 2003 13:49:28   WuQ
 * Changes related to saving user's original FONTCONTEXT in IF_STATE.
 * 
 *    Rev 1.268   Aug 05 2003 16:42:38   WuQ
 * Added the check of whether  the user provides too many fonts.
 * 
 *    Rev 1.267   Aug 04 2003 10:27:06   WuQ
 * Fixed the problems of parameters passed in to function LFNT_MAKifbmheader(). 
 * 
 *    Rev 1.266   Aug 01 2003 18:04:12   Galejs
 * fix for CCC error 600 (by jfd), plus some compiler fixes
 * 
 *    Rev 1.265   Aug 01 2003 16:02:20   WuQ
 * Removed fc_updated from if_state.
 * Removed functions: Find_CMAP_3_10(), linkedFontListCreate(), SetFontContext() and linkedFontListDestroy().
 * LFNT_MAKifbmheader() is called for linked font instead of MAKifbmheader().
 * 
 *    Rev 1.264   Jul 21 2003 18:33:56   Galejs
 * add UFST_debug_on(), UFST_debug_off(), UFST_get_debug() calls (to access if_state.trace_sw)
 * 
 *    Rev 1.263   Jul 15 2003 12:44:02   Doolittl
 * TT Performance fix, to avoid calling comp_pix() again when CGIFfont() is called more than once with same FC structure.
 * 
 *    Rev 1.262   Jul 15 2003 11:47:00   Doolittl
 * Revised handling for PCLExxO download with symbol set not found in *.ss files.
 * 
 *    Rev 1.261   Jul 14 2003 17:59:22   WuQ
 * if_state.fc_updated is used to control whether user's initial fontcontext setting need to be copied.
 * Changes of the parameter list for function linkedFontListCreate().
 * CGIFfont_access() calls are replaced by setting if_state.font_access in LINKED_FONT related code.
 * 
 *    Rev 1.260   Jul 11 2003 12:06:14   Galejs
 * replace cache_by_ref_mode tests with CACHE_BY_REF tests
 * 
 *    Rev 1.259   Jul 01 2003 18:08:42   Galejs
 * CGIFinitRomInfo - don't initialize pss_directory[] if NO_SYMSET_MAPPING
 * 
 *    Rev 1.258   Jun 30 2003 17:34:02   WuQ
 * changes for linked fonts
 * 
 *    Rev 1.257   Jun 30 2003 17:26:22   WuQ
 * changes for linked fonts
 * 
 *    Rev 1.256   Jun 27 2003 16:24:18   WuQ
 * changes for linked fonts
 * 
 *    Rev 1.255   Jun 25 2003 14:02:10   Galejs
 * update UFST version to "4.6 pre-alpha"
 * 
 *    Rev 1.254   Jun 23 2003 16:13:56   Galejs
 * missing reentrancy parm; several customer-requested inits; debug & preprocessor cleanup; get rid of NON_IF_FONT
 * 
 *    Rev 1.253   Jun 12 2003 15:51:42   Joe
 * Added "cache-by-reference" support.
 * 
 *    Rev 1.252   Jan 10 2003 12:05:46   Galejs
 * update version string to "" (for final release)
 * 
 *    Rev 1.251   Jan 07 2003 15:13:46   Joe
 * Added comment describing last change.
 * 
 *    Rev 1.250   Jan 07 2003 14:57:14   Joe
 * In CGIFbmheader(), fixed "hanging" problem when switching from
 * plugins to STIK fonts.
 * 
 *    Rev 1.249   Jan 03 2003 15:29:20   Galejs
 * update version string to "release candidate"
 * 
 *    Rev 1.248   Nov 27 2002 13:09:26   Galejs
 * update version string to "beta"
 * 
 *    Rev 1.247   Nov 26 2002 17:54:24   Galejs
 * add cast to MEMptr() call; conditional include of unistd.h
 * 
 *    Rev 1.246   Nov 20 2002 15:10:30   Doolittl
 * Added CGIFbucket_purge() functionality.
 * 
 *    Rev 1.245   Nov 19 2002 08:57:52   AOF
 * Replaced CMAP_QUERY with NAME_QUERY in CGIFtt_name_query. Unix build error fix.
 * 
 *    Rev 1.244   Nov 15 2002 11:04:30   Galejs
 * fix SUN build errors in CGIFtt_name_query, CGIFwhat_version
 * 
 *    Rev 1.243   Nov 04 2002 09:02:18   Joe
 * In CGIFwidth(), free handle after calling CGIFchar_handle().
 * 
 *    Rev 1.242   Oct 28 2002 11:11:48   Galejs
 * NO_SYMSET_MAPPING version of CGIFwidth (for jwd - bug 90); add CGIFwhat_version()
 * 
 *    Rev 1.241   Oct 24 2002 14:11:32   Galejs
 * add CGIFtt_name_query() function (bug/enhancement # 57)
 * 
 *    Rev 1.240   Oct 23 2002 13:53:50   Joe
 * In CGIFfont(), removed code which calculates "lpm", "xlpm" and "ylpm"
 * (moved to matrix_to_scale()).
 * 
 *    Rev 1.239   Oct 04 2002 14:46:38   Galejs
 * add (FILECHAR*) cast to two OPEN stmts
 * 
 *    Rev 1.238   Oct 03 2002 18:15:54   Galejs
 * FS_ISTT should be FC_ISTT
 * 
 *    Rev 1.237   Sep 30 2002 15:10:54   LynchR
 * Updated 32-bit charcode support in 
 * CGIFchar and CGIFchar_size.
 * 
 *    Rev 1.236   Sep 30 2002 13:46:06   Galejs
 * 32-bit charcode support
 * 
 *    Rev 1.235   Sep 26 2002 20:04:16   Galejs
 * compiler warning fixes, one reentrancy fix
 * 
 *    Rev 1.234   Sep 26 2002 10:55:22   Joe
 * Extract "HOxo" metrics for stroke fonts.
 * 
 *    Rev 1.233   Sep 23 2002 20:26:00   Galejs
 * add DIMM_DISK option (bug # 92) (for awr)
 * 
 *    Rev 1.232   Sep 10 2002 15:02:42   Joe
 * In CGIFfont(), set "if_state.lpm" to "fc->ylpm" for
 * !SCALE_MATRIX and for TYPO_SCALE_MATRIX.
 * 
 *    Rev 1.231   Sep 06 2002 17:45:52   Galejs
 * fix Purify warning, reentrancy problem (bug # 3, 10)
 * 
 *    Rev 1.230   Sep 03 2002 17:04:16   Galejs
 * fix too-small filehandle in TT query functions (bug # 26)
 * 
 *    Rev 1.229   Aug 27 2002 16:52:02   Joe
 * Added fix for rotated stroke fonts with MAT0
 * (by swp).
 * 
 *    Rev 1.228   Aug 19 2002 10:02:18   Joe
 * In CGIFfont(), added fix for calculation of "xlpm" and "ylpm"
 * in MAT0 mode which had caused problems for STIK fonts
 * (from swp).
 * 
 *    Rev 1.227   Apr 22 2002 17:53:10   Galejs
 * remove obsolete USE_SURFER_API references (UFST bug #8)
 * 
 *    Rev 1.226   Mar 28 2002 14:43:28   Joe
 * Format 11 changes:
 * 1.) In CGIFfont(), if unbound pcleo, set
 * "usePlugins" to TRUE.
 * 
 *    Rev 1.225   23 Jan 2002 08:58:24   JOE
 * In CGIFfont(), set default stroke percent to 3% for stik fonts.
 * 
 *    Rev 1.224   Jan 15 2002 14:00:24   Joe
 * Added Stik font support.
 * 
 *    Rev 1.223   04 Sep 2001 09:12:06   JOE
 * NOSYMSET / CACHE / PS bug fix.
 * 
 *    Rev 1.222   24 Aug 2001 14:30:52   JOE
 * Removed CTRL/Z at end of file.
 * 
 *    Rev 1.221   24 Aug 2001 14:18:52   JOE
 * PCLEO changes (by jfd / jwd).
 * 
 *    Rev 1.220   Jun 15 2001 18:19:00   Galejs
 * in CGIFFont_metrics, zero out structure at start
 * 
 *    Rev 1.219   May 03 2001 20:17:38   Galejs
 * data-type cleanup (+ tighter conditional compiles)
 * 
 *    Rev 1.218   Apr 02 2001 16:26:40   Al
 * Removed fixed size array from ACT memory management
 * 
 *    Rev 1.217   Dec 05 2000 14:47:38   Galejs
 * add CGIFtt_cmap_query(); use new macro is_it_Asian()
 * 
 *    Rev 1.216   Nov 28 2000 19:04:36   Galejs
 * remove obsolete PST1, FCO_TT, PCLEO options
 * 
 *    Rev 1.215   Oct 06 2000 14:10:38   Al
 * Fixed non ANSI header in CGIFtt_query()
 * 
 *    Rev 1.214   04 Oct 2000 08:56:26   JOE
 * In CGIFfont(), calculate 'xlpm' and 'ylpm' instead of just 'lpm'
 * and remove conditional compile based on WINDCOMP.
 * 
 *    Rev 1.213   19 Apr 2000 15:54:32   JOE
 * In CGIFfont(), store 'lpm' in 'if_state.fcCur.lpm'.
 * 
 *    Rev 1.212   Mar 29 2000 13:48:50   galejs
 * fix massively messed-up indents
 * 
 *    Rev 1.211   27 Mar 2000 14:57:04   JOE
 * CACHE with NO_SYMSET_MAPPING fix (by jwd).
 * 
 *    Rev 1.210   Feb 04 2000 18:30:50   galejs
 * fix types in system calls (for ks)
 * 
 *    Rev 1.209   Feb 04 2000 17:12:54   galejs
 * include <io.h> (for open, close prototypes)
 * 
 *    Rev 1.208   04 Feb 2000 15:20:16   PVCSADMN
 * Reentrancy changes (by ks).
 * 
 *    Rev 1.207   03 Feb 2000 16:14:26   JOE
 * ttquery changes (by ks).
 * 
 *    Rev 1.206   03 Feb 2000 15:32:38   AL
 * Changed SWP799 to WINDCOMP
 * 
 *    Rev 1.205   Feb 03 2000 11:40:20   galejs
 * simultaneous disk/ROM not conditional on SIMULDISKROM any more
 * 
 *    Rev 1.204   Feb 02 2000 13:27:44   galejs
 * simultaneous disk/rom changes (for jd)
 * 
 *    Rev 1.203   Jan 28 2000 14:59:42   galejs
 * compile fix in CGIFwidth (CFF & CHAR_HANDLE)
 * 
 *    Rev 1.202   Jan 24 2000 13:11:10   galejs
 * vertical-writing changes (for keb); compile fixes in CGIFfont()
 * 
 *    Rev 1.201   Dec 10 1999 16:39:46   galejs
 * get rid of TT_ROM1 option
 * 
 *    Rev 1.200   Nov 15 1999 12:09:36   galejs
 * use memcpy() rather than FCcopy() in CGIFfont()
 * 
 *    Rev 1.199   17 Sep 1999 08:29:08   JOE
 * Added code to compute "fc->lpm" -- needed for new quadvectorize (by swp).
 * 
 *    Rev 1.198   26 Aug 1999 15:17:50   JOE
 * UsePlugins member of the new Bucket was not initialized properly
 * when CGIFsegments() was called before CGIFfont() (by ks).
 * 
 *    Rev 1.196   Aug 17 1999 12:02:02   galejs
 * include-file changes; UFST_MSDOS, USING_16_BIT_DOS tests
 * 
 *    Rev 1.195   29 Jul 1999 17:30:42   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.194   24 Jun 1999 11:34:54   JOE
 * 
 * In CGIFfont(), no longer calling get_tt...() functions to retrieve
 * platform and specific IDs. (This is now done in ttload...() functions.)
 * 
 *    Rev 1.193   May 24 1999 15:11:50   galejs
 * make ACT reentrant
 * 
 *    Rev 1.192   25 Mar 1999 11:16:28   JOE
 * Conditionally compile PSEUDO_HALF_WIDTH code (by keb).
 * 
 *    Rev 1.191   10 Mar 1999 10:41:22   DAVID
 * In CGIFwidths(), added conditional code for CFF cases to establish
 * at least one character 'reference environmant' before getting widths.
 * 
 *    Rev 1.190   18 Feb 1999 15:09:02   JOE
 * Fix IF plugin problem with NO_SYMSET_MAPPING enabled. Modified
 * CGIFfont() to only set if_state.usePlugins to FALSE for external
 * soft fonts with NO_SYMSET_MAPPING (by ks).
 * 
 *    Rev 1.189   09 Feb 1999 19:12:56   GALEJS
 * remove unused include file types.h
 * 
 *    Rev 1.188   21 Jan 1999 14:17:58   GALEJS
 * standardize #include tests (plus some compiler warnings)
 * 
 *    Rev 1.187   13 Jan 1999 14:22:38   MARTIN
 * Removed status declaration.
 * 
 *    Rev 1.186   12 Jan 1999 17:20:16   GALEJS
 * use CONST for read-only data; move EXTERN dcls
 * 
 *    Rev 1.185   09 Dec 1998 08:32:00   JOE
 * Restored conditional compile of call to SYMnoMap() (by jwd).
 * 
 *    Rev 1.183   15 Oct 1998 15:27:18   JOE
 * Changed conditional compile of SYMnoMap() (by ks).
 * 
 *    Rev 1.182   25 Aug 1998 15:29:50   JOE
 * Repaired CGIFbound_box() function declaration (by jwd).
 * 
 *    Rev 1.181   21 Aug 1998 14:21:58   AL
 * Removed cgif_Char_Handle
 * 
 *    Rev 1.180   17 Aug 1998 10:57:42   AL
 * Fixed CGIFps()
 * 
 *    Rev 1.179   06 Aug 1998 15:41:48   AL
 * Changed !ROM to DISK_FONTS
 * 
 *    Rev 1.178   08 Jul 1998 15:10:46   GALEJS
 * add initializations for XLfont, Surfer-vbl if_state elts
 * 
 *    Rev 1.177   22 Jun 1998 18:18:06   GALEJS
 * final set of reentrancy parm-passing changes
 * 
 *    Rev 1.176   15 Jun 1998 15:08:04   GALEJS
 * get rid of MULTICALLER; parm-passing changes for reentrancy
 * 
 *    Rev 1.175   29 May 1998 17:18:30   GALEJS
 * add init for some /psi vbls in if_state
 * 
 *    Rev 1.174   11 May 1998 13:58:38   JOE
 * Removed condition which included 'ttroment.h' based on
 * TT_ROM_ACT being enabled (by keb).
 * 
 *    Rev 1.173   15 Apr 1998 17:28:18   GALEJS
 * chr_def_hdr, symbolset in IF_STATE; init for hchar_buf
 * 
 *    Rev 1.172   14 Apr 1998 18:49:54   GALEJS
 * fontindex now in IF_STATE; init for special_case 
 * 
 *    Rev 1.171   13 Apr 1998 13:12:38   AL
 * Moved MLOCAL pathname to IF_STATE to fix disk font input
 * 
 *    Rev 1.170   02 Apr 1998 20:01:40   GALEJS
 * move 3 GLOBALs to IF_STATE, add code to init_former_globals()
 * 
 *    Rev 1.169   01 Apr 1998 19:01:26   GALEJS
 * CGIFinitstate (and others) now in IF_STATE
 * 
 *    Rev 1.168   31 Mar 1998 18:55:30   GALEJS
 * add init_former_globals() function (called from CGIFinit())
 * 
 *    Rev 1.167   27 Mar 1998 10:34:38   JOE
 * In CGIFchar(), added a check to return an error code if banding is
 * specified with a scaling matrix other than Typographer.
 * In same function, conditionally compiled check of rotation angle
 * for cases of !SCALE_MATRIX and TYPO_SCALE_MATRIX.
 * 
 *    Rev 1.166   26 Mar 1998 16:57:38   GALEJS
 * kanji.h now in shareinc.h
 * 
 *    Rev 1.165   24 Mar 1998 16:30:52   GALEJS
 * include-file changes
 * 
 *    Rev 1.164   03 Mar 1998 16:07:44   JOE
 * Added ASIANVERT code (by dah).
 * 
 *    Rev 1.163   03 Mar 1998 12:48:26   GALEJS
 * #if ASIAN_VERT, not #ifdef
 * 
 *    Rev 1.162   23 Feb 1998 14:46:06   AL
 * Added Dale's ASIANVERT in char size
 * 
 *    Rev 1.161   13 Feb 1998 12:51:38   AL
 * VLC support for CGIFbound_box()
 * 
 *    Rev 1.160   10 Feb 1998 17:15:52   GALEJS
 * just a few additional DBG statements
 * 
 *    Rev 1.159   30 Jan 1998 16:25:44   GALEJS
 * remove unused TT plugin options; some IFCONFIG fields disk-only
 * 
 *    Rev 1.158   28 Jan 1998 12:11:18   AL
 * Added pointer to if_state as parameter to comp_pix()
 * 
 *    Rev 1.157   26 Jan 1998 15:33:16   JOE
 * Makechar() is conditionally defined based on CACHE or CHAR_HANDLE (by keb)
 * 
 *    Rev 1.156   21 Jan 1998 09:38:12   DAVID
 * Added #if ASIAN_ENCODING to code segments that call ASIANexit() - to elimin
 * 
 *    Rev 1.155   21 Nov 1997 16:13:12   MIKE
 * fco_saveHndl() call is conditional on #if PLUGINS
 * 
 *    Rev 1.154   29 Sep 1997 18:52:56   MIKE
 * Remove ^Z at end of file
 * 
 *    Rev 1.153   16 Sep 1997 14:54:52   GALEJS
 * fix compile for ARM/Helios
 * 
 *    Rev 1.152   15 Sep 1997 11:30:18   JOE
 * Repaired compiler error which occurs if GRAYSCALING and CHAR_SIZE
 * are both enabled. Data item "fcCur" needs to be passed as ptr to
 * FC_ISGRAY macro (by jwd).
 * 
 *    Rev 1.151   06 Sep 1997 22:28:06   MIKE
 * In CGIFfont_metrics(), changed "act" back to "mtx"
 * 
 *    Rev 1.150   04 Sep 1997 17:16:38   MARTIN
 * Modified referecnces to AGFA Compressed TrueType (ACT).
 * 
 *    Rev 1.149   03 Sep 1997 17:35:36   GALEJS
 * no need for path vbls if not using DISK mode
 * 
 *    Rev 1.148   03 Sep 1997 15:33:46   JOE
 * The following changes were made to resolve the PS banding/space char 
 * problem:
 * In cgif_Tile(), if bitmap_tile() returns an "invalid_tile" error,
 * return the derederenced handle to the caller.
 * In CGIFchar(), if cgif_Tile() returns an "invalid_tile" error,
 * store the escapement and em box size in the IFBITMAP structure.
 * 
 *    Rev 1.147   21 Aug 1997 15:42:50   JOE
 * In cgif_Font(), after calling get_ttROM...ids(), check return
 * value for possible error.
 * 
 *    Rev 1.146   14 Aug 1997 17:32:48   MARTIN
 * Modified cgif_Font to test for ENTITYACT.
 * 
 *    Rev 1.145   31 Jul 1997 15:03:32   MARTIN 
 * Moved FC_ACT_TYPE to ExtndFlags.
 * 
 *    Rev 1.144   15 Jul 1997 11:54:34   AL 
 * Removed test of invalid bold that is no longer needed
 * 
 *    Rev 1.143   30 Jun 1997 10:03:28   JOE 
 * Resolved conflict between ASIAN_ENCODING and HQ2 handling (by Jimmy).
 * 
 *    Rev 1.142   16 Jun 1997 19:11:12   GALEJS
 * fix SIGNEDCHAR NO compile
 * 
 *    Rev 1.141   16 Jun 1997 14:28:22   AL 
 * Can have GRAYSCALING without CGBITMAP
 * 
 *    Rev 1.140   04 Jun 1997 18:18:32   DAVID 
 * In cgif_Font() added WANSUNG and JOHAB Korean encoding to ASIAN encodings.
 * Also added new 1st parameter to get_ttDISK-ids() and get_ttROM_ids() for
 * enabling searching for match of requested encoding with cmap tables in
 * TrueType fonts that have more than one cmap table and different encodings
 * in each.
 * 
 *    Rev 1.139   30 May 1997 09:48:38   MARTIN 
 * Added TrueType ROM ACT (compressed random access).
 * 
 *    Rev 1.138   08 May 1997 20:06:42   MIKE 
 * Added check for error in CGIFfont_metrics()
 * 
 *    Rev 1.137   17 Apr 1997 12:12:36   DAVID
 * Removed all Galley Segment Processing recently added.  This will be
 * supported in 'ttset_char()' in 'tt_if.c' instead.
 * 
 *    Rev 1.136   07 Apr 1997 09:45:56   JOE
 * Changed return type of "check_galley()" function declaration to
 * MLOCAL so that if agrees with function prototype.
 * 
 *    Rev 1.135   03 Apr 1997 19:25:42   MIKE
 * Fix grayscale CGIFbound_box() for SUBPIX alignment
 * 
 *    Rev 1.134   02 Apr 1997 17:10:26   MIKE
 * Fixed typo in CGIFfont_metrics definition.
 * 
 *    Rev 1.133   27 Mar 1997 12:15:48   GALEJS
 * fix bad cast in get_ttROM_ids() call
 * 
 *    Rev 1.132   25 Mar 1997 15:19:10   DAVID
 * Corrected reference to CHAR, which should have been CACHE.
 * 
 *    Rev 1.131   25 Mar 1997 11:56:28   DAVID 
 * Added prototypes for check_galley() and size_check_galley().
 * 
 *    Rev 1.130   25 Mar 1997 10:45:12   DAVID 
 * Added check_galley() and size_check_galley() routines, and calls in
 * cgif_Char_Handle(), CGIFchar(), and CGIFchar_size() for support of
 * Galley Character Segment processing.
 * 
 *    Rev 1.129   24 Mar 1997 14:57:24   DAVID
 * No change.
 * 
 *    Rev 1.128   21 Mar 1997 15:12:16   MIKE
 * Add call to grayexit(); change call to grayfont().
 * 
 *    Rev 1.127   15 Jan 1997 09:19:02   DAVID
 * Removed PST1-PCLEOI option as part of project to trim ufst.
 * 
 *    Rev 1.126   14 Jan 1997 16:49:44   DAVID
 * Removed MULTIFORMAT option as part of project to trim ufst.
 * 
 *    Rev 1.125   13 Jan 1997 14:06:56   DAVID
 * Removed CONVERGENT_FONTS option as part of project to trim ufst.
 * 
 *    Rev 1.123   09 Jan 1997 17:44:16   DAVID
 * Put TRACK_KERN_KEY, TEXT_KERN_KEY, and DESIGN_KERN_KEY back in
 * case statement - for now.
 * 
 *    Rev 1.122   08 Jan 1997 13:55:06   DAVID
 * Deleted KERN option as part of project to trim ufst.
 * 
 *    Rev 1.121   02 Jan 1997 17:22:28   DAVID
 * Added GB, BIG5, and KSC support.  Added tt_langID field to help
 * distinguish between GB and BIG5 encoded asian fonts.
 * 
 *    Rev 1.120   18 Nov 1996 19:23:52   MIKE
 * Clean up CGIFfont_metrics
 * 
 *    Rev 1.119   14 Nov 1996 21:03:16   MIKE
 * Undo 9/3/96 change -- enable plugins in cgif_Font() if ASIAN_ENC
 * 
 *    Rev 1.118   07 Nov 1996 11:27:04   MIKE
 * Fixed CGIFchar() bug, grayscale space wasn't returning ERR_fixed_space
 * 
 *    Rev 1.117   06 Nov 1996 15:06:36   MIKE
 * Added new API call, CGIFfont_metrics()
 * 
 *    Rev 1.116   16 Oct 1996 16:34:22   JOE
 * In CGIFchar(), when checking for space character, test if
 * processing bitmap or outline.
 * 
 *    Rev 1.115   04 Oct 1996 09:10:40   JOE
 * Removed CTRL-Z at end of file.
 * 
 *    Rev 1.114   01 Oct 1996 16:44:28   JOE
 * Implemented new ASIAN cache architecture.
 * 
 *    Rev 1.113   18 Sep 1996 11:49:40   MIKE
 * Fix divide by zero fault in bbox_union()
 * 
 *    Rev 1.112   04 Sep 1996 13:01:20   MIKE
 * Don't use plugins for Asian encodings. Fixed CGIFbound_box() problems.
 * 
 *    Rev 1.111   06 Aug 1996 15:30:48   MIKE
 * Fixed CGIFwidth() -- ASIAN.
 * 
 *    Rev 1.110   05 Feb 1996 13:41:34   MIKE
 * In CGIFchar(), CGIFchar_size(), release_semaphor wasn't called for space ch
 * 
 *    Rev 1.109   24 Jan 1996 17:25:08   AL
 * Compressed cache
 * 
 *    Rev 1.108   22 Dec 1995 13:28:38   MERRILL
 * change conditionals for TTplugin && !FCO_RDR
 * 
 *    Rev 1.107   21 Dec 1995 15:08:04   MERRILL
 * spelling change gray
 * 
 *    Rev 1.106   22 Nov 1995 11:18:08   MIKE
 * #include <stdlib.h> for _OSK or _OS9000 environments
 * 
 *    Rev 1.105   14 Nov 1995 11:39:26   MERRILL
 * Removed formatting of #if
 * 
 *    Rev 1.103   18 Oct 1995 11:40:52   MERRILL
 * Added some formatting of #if  nestings.
 * 
 *    Rev 1.101   05 Oct 1995 15:39:50   AL
 * Cond compile "status" var decl to work with GRAYSCALING and CHAR_HANDLE
 * 
 *    Rev 1.100   04 Oct 1995 17:10:52   AL
 * Grayscaling
 * 
 *    Rev 1.99   04 Aug 1995 16:21:10   JC
 * Changed fco y fluff from 2 to 5 because of perthousand character.
 * 
 *    Rev 1.98   04 Aug 1995 15:13:24   JC
 * In CGIFfco_access(), corrected args - psize and pbuffer (misspelling)
 * 
 *    Rev 1.97   03 Aug 1995 11:48:26   MIKE
 * In CGIFbound_box() increased FCO fluff to 4 in X, 2 in Y
 * 
 *    Rev 1.96   28 Jul 1995 16:57:28   JWD
 * Added release_semaphor() call to CGIFtt_Free() before exit.
 * 
 *    Rev 1.95   28 Jul 1995 10:22:40   JWD
 * Initialized lsize[] array in routine CGIFchar_size().
 * 
 *    Rev 1.94   18 Jul 1995 13:29:16   MIKE
 * CGIFfont_purge(), CGIFhdr_font_purge().
 * 
 *    Rev 1.93   13 Jul 1995 14:15:00   MIKE
 * Conditionally compile CGIFsegments() if IF_RDR=1
 * 
 *    Rev 1.92   28 Jun 1995 16:13:28   MIKE
 * CGIFbound_box()
 * 
 *    Rev 1.91   24 May 1995 19:55:06   MIKE
 * CGIFbound_box, CGIFwidth, CGIFfco_Close, CGIFfco_Plugin.
 * 
 *    Rev 1.90   18 Apr 1995 16:53:10   JOE
 * Changes to support the removal of symbol set mapping.
 * 
 *    Rev 1.89   10 Apr 1995 16:20:06   MIKE
 * Conditionally compiled CGIFfco_Access()
 * 
 *    Rev 1.88   07 Apr 1995 08:37:00   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.87   31 Mar 1995 11:12:52   JWD
 * Added support for CGIFfco_Access().
 * 
 *    Rev 1.86   27 Mar 1995 10:40:52   MARTIN
 * Modified CGIFtt_Free to use a pointer instead of a handle.
 * 
 *    Rev 1.85   16 Feb 1995 16:46:46   JOE
 * Corrected prototype for CGIFtt_Generate() based on HUGE_PTR_SUPPORT.
 * 
 *    Rev 1.84   13 Jan 1995 18:05:08   ROB
 * Support for > 64KB memory blocks in DOS.
 * 
 *    Rev 1.83   09 Jan 1995 10:33:12   MARTIN
 * Added new arg to CGIFtt_Generate.
 * 
 *    Rev 1.82   17 Dec 1994 09:42:12   MIKE
 * Fixed CGIFbound_box() for FC_FCO_TYPE
 * 
 *    Rev 1.81   14 Dec 1994 15:46:56   JWD
 * Added support for MULTICALLER in FCO-related functions.
 * Removed MULTICALLER dependency from CAChdr_purge() prototype.
 * 
 *    Rev 1.80   14 Dec 1994 08:20:54   ROB
 * Changed arg 2 of CGIFtt_Generate() from LPLPUB8 to LPHPUB8.
 * 
 *    Rev 1.79   02 Dec 1994 21:13:22   YAN
 * KSC.
 * 
 *    Rev 1.78   24 Oct 1994 09:57:12   JOE
 * In CGIFexit(), changed the way "CGIFinitstate" is tested based on IF_RDR
 * to resolve memory leakage problem.
 * 
 *    Rev 1.77   20 Oct 1994 14:09:50   MIKE
 * Changed argument of CGIFtt_Free() to SW16.
 * 
 *    Rev 1.76   19 Oct 1994 17:21:48   MIKE
 * Fixed CGIFbound_box() problem for mirrored matrix states.
 * Changed args of CGIFfco_Close and CGIFfco_Plugin from "int" to "SW16".
 * 
 *    Rev 1.75   11 Oct 1994 16:16:16   MARTIN
 * Modified CGIFexit, added &&!FCO_RDR to logical so that we clean up properly
 * 
 *    Rev 1.74   10 Oct 1994 12:20:40   MIKE
 * In cgif_Font(), resolve fontcontext matching problem by always setting
 * if_state.cur_loc_fc.font_hdr to 0.
 * 
 *    Rev 1.73   26 Sep 1994 11:03:50   MIKE
 * Changed CGIFfco_Open to pass int* argument to fco_InitFCO instead of UW16*
 * 
 *    Rev 1.72   20 Sep 1994 16:17:06   ROB
 * Modified CGIFinit() so that when running Windows DLL, 'CGIFinitstate'
 * will be initialized each time (instead of by compiler).
 * 
 *    Rev 1.71   15 Sep 1994 11:46:06   JOE
 * Moved prototype for CGIFhdr_font_purge() so that it is not
 * conditionally compiled based on CACHE.
 * 
 *    Rev 1.70   15 Sep 1994 08:27:46   JOE
 * Corrected function prototype declaration for CGIFhdr_font_purge()
 * (ENTRY --> CGENTRY).
 * Corrected prototype for CAChdr_purge() ("UW16 CGENTRY" --> "EXTERN UW16").
 * Removed prototype for CAChdr_font().
 * 
 *    Rev 1.69   11 Sep 1994 09:07:48   JOE
 * Added new functifon CGIFhdr_font_purge().
 * 
 *    Rev 1.68   08 Sep 1994 20:10:08   MIKE
 * Cleanup in CGIFwidth(), -kern() to support FCO only.
 * 
 *    Rev 1.67   02 Sep 1994 12:45:24   MIKE
 * Added CGIFfco_Plugin().
 * 
 *    Rev 1.66   26 Aug 1994 08:57:18   JOE
 * Changed arg 2 of CGIFffco_Open() from 'int *' to 'LPSW16' for WINDOWS.
 * Changed args 1 and 2 of CGIFtt_Generate() ('int *' to 'LPSW16', 'LPUB8 *'
 * to 'LPLPUB8') for WINDOWS.
 * 
 *    Rev 1.65   04 Aug 1994 14:14:56   MIKE
 * Added FCO changes 1.48.1.2
 * 
 *    Rev 1.64   14 Jul 1994 10:24:44   MIKE
 * Fixed bug in CGIFfont() that was returning error 54 for PCLETTOs.
 * 
 *    Rev 1.63   13 Jul 1994 14:02:00   JOE
 * In CGIFwidth(), set if_state.awtsub_on based on fcCur.p_AltWidTab to
 * avoid potential problem that could be caused when switching between
 * conv. and non-conv. fonts for multiple threads.
 * 
 *    Rev 1.62   13 Jul 1994 09:49:06   JOE
 * In CGIFbound_box(), was not setting if_state.awtsub_on based on
 * fcCur.p_AltWidTab. This was causing a problem if switching between
 * convergent and non-convergent fonts using multiple threads.
 * 
 *    Rev 1.61   05 Jul 1994 08:16:46   MIKE
 * Add 3rd argument to PCLeo2IF_ssnum(), called from cgif_Font().
 * 
 *    Rev 1.60   15 Jun 1994 10:22:24   MIKE
 * In CGIFfont() for Foreign Bitmaps 'has_path'=0; don't call SYMnew.
 * 
 *    Rev 1.59   08 Jun 1994 13:10:58   MIKE
 * CGIFfont calls SYMnoMap for PCLEOs with downloaded symbol set.
 * 
 *    Rev 1.58   03 Jun 1994 10:04:02   JOE
 * Changed all occurrences of ENTRY to CGENTRY to resolve conflict on
 * some compilers.
 * 
 *    Rev 1.57   05 May 1994 14:20:32   MIKE
 * Fixed bug involving "if_state.awtsub_on" and font bounding box.
 * 
 *    Rev 1.56   25 Apr 1994 13:56:06   MIKE
 * For FONTBBOX: changed structure IFplugin->xmax because of new "plugin.cfp"
 * 
 *    Rev 1.55   21 Apr 1994 16:48:58   JOE
 * Changed the way CGIFsegments() interprets the "tfnum" argument.
 * Instead of basing it on DYNAMIC_FONTS, it now checks for SEGACCESS
 * = 1 or 2 as well as DYNAMIC_FONTS.
 * 
 *    Rev 1.54   21 Apr 1994 15:43:04   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.53   25 Mar 1994 11:47:54   JOE
 * In CGIFwidth(), if processing CONVERGENT_FONTS, set "if_state.alt_width"
 * to 0 before calling CVFget_fnt_index() so that chwidth() will get called
 * if there is no entry in the alternate width table.
 * 
 *    Rev 1.52   06 Mar 1994 15:30:06   MIKE
 * Made changes to CGIFbound_box() to support Convergent Fonts/AWT4.
 * 
 *    Rev 1.51   10 Feb 1994 12:12:30   JOE
 * In CGIFsegments(), if DYNAMIC_FONTS is enabled, treat "tfnum" arg as a
 * pathname rather than a typeface number. This will all CGIFsegments() to
 * return segment data without having to call CGIFfont() first.
 * 
 *    Rev 1.50   03 Feb 1994 13:56:04   MIKE
 * For Convergent Fonts, made minor changes in CGIFwidth(). 
 * 
 *    Rev 1.49   25 Jan 1994 10:44:24   MAIB
 * Created a two-byte character code caching scheme, conditionally compiled
 * on ASIAN_ENCODING
 * 
 *    Rev 1.48   06 Jan 1994 09:42:28   JOE
 * Modified CGIFchar_size() to return the size of the largest compound
 * character part, for the cc_buf_size in the IFCONFIG structuure. Will
 * be returned in size[3].
 * 
 *    Rev 1.47   06 Jan 1994 08:32:08   MAIB
 * Fixed bug in handling alien bitmaps
 * 
 *    Rev 1.46   05 Jan 1994 18:12:56   ROB
 * Add support for "GB" encoding.
 * 
 *    Rev 1.45   05 Jan 1994 14:59:38   MAIB
 * Modified handling of alien bitmaps
 * 
 *    Rev 1.44   05 Jan 1994 09:37:40   JOE
 * In cgif_Config(), added check for bitmap width compatability with setting
 * of RASTER_ORG.
 * 
 *    Rev 1.43   14 Dec 1993 12:57:28   MIKE
 * Set xx_FLUFF constants to 1 for CGIFbound_box() function.
 * 
 *    Rev 1.42   07 Dec 1993 15:15:40   JOE
 * In cgif_Font(), added calls to get_ttDISK_ids() and get_ttROM_ids()
 * to retrieve platform and specific IDs from KANJI TT fonts.
 * Including "kanji.h".
 * 
 *    Rev 1.41   21 Nov 1993 07:59:16   MAIB
 * Added prototypes missing in multi-caller configuration
 * 
 *    Rev 1.40   11 Nov 1993 18:26:56   MIKE
 * When get_awt_bbox() is called, check status for error.
 * 
 *    Rev 1.39   01 Nov 1993 13:10:18   MAIB
 * Additional data required when switching instances
 * 
 *    Rev 1.38   27 Oct 1993 16:49:10   MIKE
 * Removed redundant code CGIFwidth().
 * 
 *    Rev 1.37   25 Oct 1993 10:57:50   MAIB
 * Optimized cache access in CGIFchar()
 * 
 *    Rev 1.36   12 Oct 1993 09:56:48   MAIB
 * put in ansi defs to allow sparc compilation
 * 
 *    Rev 1.35   11 Oct 1993 13:56:30   MIKE
 * Changes to CGIFwidth(), bound_box(), font(). See comments 9/30, 10/5.
 * 
 *    Rev 1.34   08 Oct 1993 15:04:02   JOE
 * In CGIFchar(), if requesting a fixed space character which has already
 * been cached, "status" is not being set to ERR_fixed_space. Check for
 * fixed space character and set "status" to ERR_fixed_space if necessary.
 * 
 *    Rev 1.33   29 Sep 1993 12:01:50   JOE
 * Added support for PS bounding box.
 * 
 *    Rev 1.32   29 Sep 1993 08:37:54   MAIB
 * Fixed bug of not releasing semaphore for all cases in CGIFinitRomInfo
 * 
 *    Rev 1.31   24 Sep 1993 09:19:34   JOE
 * In CGIFenter(), if MULTICALLER && !SEM_ACCESS, if "uEnterFirstTime"
 * is FALSE, "status" is returned as an ambiguous value. Initialized
 * "status" to SUCCESS at start of routine.
 * 
 *    Rev 1.30   23 Sep 1993 18:53:34   MIKE
 * Changes to CGIFfont(), CGIFbound_box().
 * 
 *    Rev 1.29   16 Sep 1993 11:27:30   MAIB
 * Changed CGIFchar() to allow banding of alien bitmaps 
 * 
 *    Rev 1.28   03 Sep 1993 13:26:52   JOE
 * Changed function declaration for psget_FontBBox() to include both
 * ANSI and non-ANSI formats to resolve compiler error.
 * 
 *    Rev 1.27   24 Aug 1993 15:27:40   JOE
 * In cgif_Font(), if symbol set is set to special encoding array value,
 * do not call PCLeo2IF_ssnum() or SYMnew().
 * 
 *    Rev 1.26   13 Aug 1993 19:35:02   MIKE
 * Replaced 2 printf's in CGIFchar() with DBG1's.
 * 
 *    Rev 1.25   03 Aug 1993 14:43:58   MAIB
 * Changed interface to resolve naming conflicts
 * 
 *    Rev 1.24   02 Aug 1993 14:20:16   MAIB
 * Changes to support multi-tasking
 * 
 *    Rev 1.23   29 Jul 1993 12:21:24   AL
 * Non-zero winding change for CGIFchar_size()
 * 
 *    Rev 1.22   15 Jul 1993 17:31:44   ROB
 * Make CGIFfont_purge() not be conditional on CACHE. Fix problem of purging
 * a PSEO and not working properly due to copy of fontcontext in if_state by
 * zeroing out this copy in font purge function.
 * 
 *    Rev 1.21   15 Jul 1993 11:59:08   MIKE
 * Changes for CGIFbbox_IFPCLEOchar(), convergent fonts; see comments.
 * 
 *    Rev 1.20   15 Jun 1993 18:32:10   MIKE
 * Added IF PCLEO support for font bbox. New routine CGIFbbox_IFPCLEOchar().
 * Added xx_FLUFF constants for CGIFbound_box(). Did some reorganization of
 * CGIFbound_box().
 * 
 *    Rev 1.19   09 Jun 1993 16:50:54   JOE
 * Changed all references to "char" to "SB8" for transportability.
 * 
 *    Rev 1.18   14 May 1993 16:08:02   JOE
 * Conditionally compiled "pathname" based on (PST1_DISK || TT_DISK ||
 * (DYNAMIC_FONTS && IF_DISK)) to resolve compiler error.
 * 
 *    Rev 1.17   06 May 1993 16:43:40   MIKE
 * In CGIFfont_purge() put conditional code around fc->font_hdr=0;
 * 
 *    Rev 1.16   06 May 1993 16:06:04   MIKE
 * Replace CGIFcache_purge() with CGIFfont_purge(). cache_purge is now a macro.
 * In CGIFfont() change "has_path" condition from NON_IF_FONT to
 *   PST1_DISK || TT_DISK || (DYNAMIC_FONTS && IF_DISK).
 *   has_path is also true for IF disk + dynamic font.
 * 
 *    Rev 1.15   22 Apr 1993 12:20:50   MIKE
 * Moved ifget_FontBBox() => fm.c.  Conditionally compile TTplugin structure.
 * 
 *    Rev 1.14   05 Apr 1993 13:27:38   MIKE
 * Fix MSC 6.0 compilation problem with ifget_FontBBox() prototype.
 * 
 *    Rev 1.13   17 Mar 1993 09:29:46   JOE
 * In CGIFchar(), if banding a PS or TT space character which exists in the
 * font or pcleo, CGIFbmheader() will not return "ERR_fixed_space", so to
 * check for space character, test for "if_state.num_loops == 0" to avoid
 * calling CGIFtile().
 * 
 * In ifget_FontBBox(), conditionally compiled declaration for "pcleoHdr"
 * based on IF_PCLEOI to resolve compiler error if !PCLEO_RDR.
 * 
 *    Rev 1.12   16 Mar 1993 10:08:40   JOE
 * Corrected function prototype for CGIFcache_purge() if !LINT_ARGS.
 * 
 *    Rev 1.11   12 Mar 1993 10:41:30   JOE
 * In CGIFchar(), if banding a fixed space character, do not tile bitmap.
 * Create bitmap untiled and cache it normally so that metric information
 * is saved.
 * 
 *    Rev 1.10   08 Mar 1993 10:19:26   JOE
 * Do not or "not_init" bit when initializing CGIFinitstate because it is
 * never utilized.
 * 
 *    Rev 1.9   03 Mar 1993 20:01:22   MIKE
 * Made code updates to CGIFbound_box().
 * 
 *    Rev 1.8   26 Feb 1993 13:05:16   JOE
 * In CGIFchar(), if character processed is a fixed space character,
 * cache it instead of returning prematurely.
 * 
 *    Rev 1.7   24 Feb 1993 16:31:04   JOE
 * In CGIFchar(), if BANDING is enabled but not selected, and if rotation is
 * desired, was returning an erroneous error.
 * 
 *    Rev 1.6   12 Feb 1993 13:53:32   JOE
 * VXWorks support.
 * 
 *    Rev 1.5   05 Feb 1993 13:31:56   MIKE
 * Added CGIFbound_bbox(). Also ifget_FontBBox(), psget_FontBBox(); should move
 * these two somewhere else
 * 
 *    Rev 1.4   02 Feb 1993 17:12:34   JOE
 * In CGIFchar(), added support for horizontal banding of tiles.
 * 
 *    Rev 1.3   29 Jan 1993 09:48:36   JOE
 * In CGIFwidth(), saved corresponding em box size for each width in buffer.
 * 
 *    Rev 1.2   21 Dec 1992 15:18:14   ROB
 * Added ANSI function declarations based upon ANSI_DEFS. General cleanup.
 * 
 *    Rev 1.1   11 Dec 1992 15:30:24   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 15:25:52   LISA
 * Initial revision.
*/
/* cgif.c */
/*
 *
 *  History:
 *  original  awr 
 *  18-May-90 dET add instance handling for MS-WINDOWS
 *  23-Jul-90 awr added Blake's typePath in CGIFconfig()
 *  07-Aug-90 awr in CGIFfont(), free previous FONT if no bitmaps
 *  13-Aug-90 awr added return SUCCESS in CGIFexit to match MULTICALLER
 *                version.
 *  18-Aug-90 awr added making_bold parameter in call to MAKfontSize()
 *                in CGIFchar_size()
 *  24-Aug-90 jfd in CGIFpcleo(), changed "ENTRY UWORD" to "UWORD ENTRY";
 *                in CGIFpcleo(), changed argument to INSTsetState()
 *                from "CallerId" to "uCallerId"
 *  28-Aug-90 dET moved uInitFirstTime and uEnterFirstTime declarations
 *                and reset these upon CGIFexit().
 *  20-Nov-90 dET In CGIFchar_size(), added "UWORD status" for MULTICALLER
 *  03-Dec-90 dET Moved "cgconfig.h" to after "port.h" and before "cgif.h"
 *  19-Dec-90 jfd IFB on a Printer changes:
 *                1.) Keep local copy of font context regardless of CACHE.
 *                2.) In CGIFfont(), store local copy of font context
 *                    regardless of CACHE.
 *                3.) In CGIFwidth(), call IXget_fnt_index() with an
 *                    argument of type (FONTCONTEXT *) regardless of CACHE.
 *                4.) In CGIFkern(), call IXget_fnt_index() with an
 *                    argument of type (FONTCONTEXT *) regardless of CACHE.
 *                5.) In CGIFpcleo(), call IXget_fnt_index() with an
 *                    argument of type (FONTCONTEXT *) regardless of CACHE.
 *                    (double-check this!!!)
 *                6.) Added routine CGIFsegments() after removing it from
 *                    file "segments.c". Had to include "segments.h" and
 *                    "ix.h". In call to IXget_fnt_index(), changed 
 *                    argument from (LONG) to (FONTCONTEXT *).
 *                7.) In CGIFchar() and CGIFchar_size(), commented out
 *                    line "chId -= ss_first_code;"
 *   3 Jan 91 ss  Added ROM support 
 *
 *  16-Jan-91 jfd In CGIFwidth(), when calling MAKchar_width(), pass
 *                "chId" instead of "chId - ss_first_code"
 *  17-Jan-91 awr Removed ERRinvalid_seg_key and moved it into cgif.h
 *  28-Jan-91 jfd Made size args of CGIFchar_size() call
 *                conditional based on (MAX_BM_BITS > 16).
 *                Declared "ccBufferSize" and "cfg->cc_buf_size"
 *                conditionally based on MAX_BM_BITS > 16.
 *  30-Jan-91 dET added prototype function definitions for MSC.
 *  31-Jan-91 dET Modify for MSC multi-model compilation.
 *   3-Feb-91 awr Made size arg to MAKfontSize() a PLONG
 *                changed mem_fund[] to a LONG.
 *                changed cc_size to LONG
 *                Renamed IXnew_ss() to SYMnew() for new module.
 *   5-Feb-91 awr Renamed MAKkern() to kern() for new module.
 *                Renamed MAKchar_width to chwidth for new module.
 *   8-Feb-91 awr Removed FCcopy_fc(), coded in line.
 *                Added dll.h to declare functions.
 *                Moved FNTfree() call in CGIFfont() to start of FNTfind().
 *                Renamed FNTfind() to CACfont().
 *                Added #include "instance.h" to declare multicaller fncts.
 *   9-Feb-91 awr Added #include "sym.h" to declare symbol set fncts.
 *  10-Feb-91 awr Moved making_bold to SCALE structure- removed parameter
 *                in MAKfontSize().
 *  15-Feb-91 awr changed IXfind_bucket() name to BUCKfind()
 *  23-Feb-91 awr Changed bucket sub-segment handles to offsets.
 *  04-Mar-91 jfd In CGIFinitRomInfo(), changed field name pfont_block to
 *                pfnt_index and removed declaration for "status".
 *                Returning SUCCESS in CGIFinitRomInfo() .
 *                Added correct function prototype for CGIFinitRomInfo().
 *  05-Jun-91 jfd Added routine CGIFcache_purge() which will call
 *                CACpurge() to purge the font in the current font 
 *                context and all its associated bitmaps.
 *                (FIX FROM EARLIER VERSION)
 *  10-Jun-91 jfd Added module CGIFps() for PostScript Type 1 output
 *                Made declaration of routine MAKifbmheader() conditional
 *                based on TILE
 *  11-Jun-91 jfd Added declaration for ps_write().
 *  17-Jun-91 jfd Moved "debug.h" after "port.h".
 *                Moved "cgconfig.h" before "port.h".
 *  19-Jun-91 jfd In CGIFps(), changed arguments.
 *                In ps_write(), changed arguments.
 *  21 Jun 91 ss  Moved prototype for fgseg() from ix.h.
 *  02-Jul-91 rs  Modified CGIFkern() to NOT subtract 'first_code' before
 *                calling kern().
 *  02-Jul-91 jfd In CGIFps(), removed "pssize" argument from CGIFps() and
 *                ps_write() functions, and am calling ps_write() conditionally
 *                based on MULTICALLER.
 *  25-Jul-91 jfd Added argument PPARAMSTR to CGIFps() because of unresolved
 *                external when attempting to build DLL.
 *  07-Aug-91 jfd Including "ps_type1.h".
 *                Added GLOBAL declaration for "PSparam_str".
 *                Changed CGIFps() function declaration from GLOBAL UWORD
 *                to UWORD ENTRY
 *  14-Aug-91 jfd Added CGIFtile().
 *  18-Aug-91 awr Added htileBM to keep track of tile bm memory
 *  25-Sep-91 jfd In CGIFcache_purge(), changed argument type from
 *                (FONTCONTEXT *) to PFONTCONTEXT to get rid of compiler 
 *                warning.
 *                Added function prototype for pcleo() to get rid of
 *                compiler warning.
 *  29-Sep-91 awr Added CGIFinitstatus
 *  14-Oct-91 jfd Added function prototype for BUCKfind() if LINT_ARGS to
 *                get rid of compiler warning.
 *   9 Dec 91 ss  Changed function prototype and call to pcleo() to PCLeo()
 *                to match name in pcleo.c.
 *  22-Jan-92 rs  Add support for URIP pointer callable functions. This
 *                includes IF_FUNC_TBL & IF_RAS_TBL structs as well as
 *                changes to CGIFfont().
 *  28-Jan-92 rs  Move font function setup to bucket.c.
 *  04-Feb-92 jfd Conditionally compiled IF_RAS_TBL for PST1I and TT_RDR..
 *  12-Feb-92 jfd In CGIFfont(), if processing a TT or PS font, reset
 *                the pointer to the font header in the current local
 *                font context to force comp_pix() to be called before
 *                processsing the first TT or PS character.
 *  24-Feb-92 jfd In CGIFfont(), conditionally compiled block of code
 *                which calculates "has_path" based on  EXTERN_FONT.
 *                Conditionally compiled declaration for "pathname" based
 *                on EXTERN_FONT.
 *                Conditionally compiled declaration for "bmras_cubeto"
 *                based on EXTERN_FONT.
 *                In CGIFsegments(), changed all occurrences of "b->" to
 *                "b->p.in." due to changes in BUCKET structure.
 *   7-Mar-92 awr Change CGIFfont() to not expect FC_EXTERN_TYPE     
 *  24 Mar 92 ss  Fixed casts in CGIFfont() to eliminate warnings.
 *  03-Apr-92 rs  Portability cleanup (see port.h).
 *  12 May 92 ss  Changed conditional compiles based on EXTERN_FONT to
 *                (PST1I || TT_RDR) since EXTERN_FONT is used
 *                elsewhere to mean PCLEO.
 *  21-May-92 jfd Added outline function table "olras_tbl".
 *                In CGIFfont(), if generating an outline, set "pras" to
 *                outline function table.
 *                Including "outline.h" for outline function prototypes.
 *  21-May-92 rs  Add call to 'cm_load_psname()' to CGIFenter() to load
 *                PostScript name table if enabled.
 *  27 May 92 ss  Changed hard-coded path of psname.cfg to use typePath
 *                given to us via config.c (the application.)
 *  10-Jun-92 jfd In CGIFinit(), changed "MAX_UW16" to "MAX_UWORD".
 *  14-Jun-92 rs  Add error check when calling 'cm_load_psname()'. Add
 *                call to 'cm_free_psname()' in CGIFexit().
 *   4-Jul-92 awr cc_buf_size unconditionally SL32
 *                Conditional fields on IFCONFIG
 *   8 Jul 92 ss  Added code in CGIFfont() to set font_id from pcleo font
 *                header into fontcontext so application doesn't have to.
 *  08-Jul-92 rs  Code cleanup.
 *  13-Jul-92 mby Added conditional code (TT_PCLEOI) to read font number
 *                from TrueType PCLEO. Always read in hi-lo (Motorola) order.
 *  14-Jul-92 rs  Fix CGIFfont() to work w/all PCLEXO's.
 *  21-Jul-92 awr Conditional compile changes.
 *  28-Jul-92 ss  In CGIFfont(), set if_state.has_path = 0
 *                if NON_IF_FONT && ROM are set.
 *  31 Jul 92 ss  Added code in CGIFfont() to map ss_code in PCLEO header to
 *                CG ss_num.
 *  05-Aug-92 jfd In CGIFfont(), copy *fc into fcCur via FCcopy(), which
 *                will zero out destination prior to copying. In addition,
 *                perform this operation prior to CACfont() call. In call
 *                to CACfont(), pass zero-initialized "fcCur" rather than
 *                non-initialized "fc".
 *  14-Aug-92 jfd In CGIFfont(), added check for emboldening when emboldening
 *                is disabled.
 *                In CGIFfont(), if PS pcleo or TT pcleo, when calculating
 *                "pcleo_ssnum", was calling GET_xLONG_OFF instead of
 *                GET_xWORD_OFF.
 *                Added macro GET_xWORD_OFF.
 *  02-Sep-92 jfd No longer calling cm_load_psname() and cm_free_psname().
 *                Replaced by PSdata table in "t1iscan.c".
 *                Removed define for PATH_DELIM.
 *  04-Sep-92 jfd In CGIFkern(), returning error if requesting kern data for
 *                PS or TT input.
 *  11-Sep-92 jfd In CGIFfont(), reset the font id of the fontcontext to
 *                prevent potential problems when switching between FST's.
 *  16-Sep-92 jfd In CGIFkern(), conditionally compiled code following
 *                PS/TT check based on IF_RDR.
 *                Conditionally compiled CGIFpcleo() based on IF_RDR.
 *  30-Sep-92 awr Added CGIFtt_universal()
 *  30-Sep-92 mby CGIFfont() calls SYMnew() with 2nd argument, fc->format.
 *  05-Oct-92 mby Removed GET_xWORD and GET_xLONG macro definitions. They
 *                are already defined in sym.h.
 *  13-Oct-92 mby Fixed incorrect parameter in CGIFtt_universal()
 *  19-Oct-92 mby Changed CGIFinitRomInfo() -- symbol set pointer (2nd
 *                argument) is an array, may point to IF symbol set block,
 *                TT symbol set block, or both.
 *  21-Oct-92 mby Include "cgmacros.h" for GET_x...() macros.
 *  21-Oct-92 rs  Fix CGIFtt_universal declarations for Windows.
 *  26-Oct-92 jfd Changed first arg of call to PCLeo2IF() from LPUW16
 *                tp PFONTCONTEXT to match actual function.
 *  21-Dec-92 rs  Add ANSI function declarations based on ANSI_DEFS.
 *  28-Jan-93 jfd In CGIFwidth(), store em box size after each width in
 *                buffer.
 *  01-Feb-93 jfd In CGIFchar(), added support for caching of horizontal
 *                bands.
 *  04-Feb-93 mby Added CGIFbound_box(), ifget_FontBBox(), psget_FontBBox()
 *                 -- should move the last two somewhere else.
 *  08-Feb-93 jfd VXWorks support.
 *  24-Feb-93 jfd In CGIFchar(), if BANDING is enabled but not requested,
 *                and if rotation is requested, was incorrectly returning
 *                "ERR_invalid_band" error.
 *  26-Feb-93 jfd In CGIFchar(), if character processed was a fixed space
 *                character, cache it to save metrics information. (Had
 *                been returning ERR_fixed space without caching.)
 *  03-Mar-93 mby Removed PFONTCONTEXT argument from CGIFbound_box().
 *                Instead of passing font context, use fcCur.
 *                Conditionally compile ps- and ifget_FontBBox().
 *                For IF PCLEO, grab bbox from header.
 *  08-Mar-93 jfd When initializing CGIFinitstate, no longer or'ing 
 *                "not_init" because it is not utilized.
 *  12-Mar-93 jfd In CGIFchar(), if banding a fixed space character,
 *                do not return prematurely after call to CGIFbmheader().
 *                Instead, give up attempt to tile character and create
 *                bitmap normally. Then cache it so that metric information
 *                is returned.
 *  16-Mar-93 jfd Corrected function prototype for CGIFcache_purge() if
 *                !LINT_ARGS.
 *  17-Mar-93 jfd In CGIFchar(), if banding a PS or TT space character which
 *                exists in the font or pcleo, CGIFbmheader() will not
 *                return "ERR_fixed_space". So to check for space, test
 *                for "if_state.num_loops == 0" to avoid calling CGIFtile().
 *                In ifget_FontBBox(), conditionally compiled declaration 
 *                for "pcleoHdr" based on IF_PCLEOI to resolve compiler
 *                error if !PCLEO_RDR
 *  01-Apr-93 mby/jwd Revised calling sequence of CGIFbound_box, to alleviate
 *                compilation anomalies generated with MS-C 6.0.
 *  21-Apr-93 mby Moved ifget_FontBBox() => fm.c. Conditionally compile
 *                TTplugin structure.
 *  05-May-93 mby Replace CGIFcache_purge() with CGIFfont_purge().
 *                CGIFcache_purge() is a macro.
 *                In CGIFfont() change has_path condition from NON_IF_FONT to
 *                PST1_DISK || TT_DISK || (DYNAMIC_FONTS && IF_DISK)
 *                Set has_path if dynamic font and IF disk.
 *  06-May-93 mby In CGIFfont_purge() put conditional around fc->font_hdr=0;
 *  14-May-93 jd  Conditionally compiled "pathname" based on
 *                (PST1_DISK || TT_DISK || (DYNAMIC_FONTS && IF_DISK)) to
 *                resolve compiler error.
 *  09-Jun-93 jfd Changed all references to "char" to "SB8" for
 *                transportability.
 *  14-Jun-93 mby Added IF PCLEO support for font bounding box. New interface
 *                routine CGIFbbox_IFPCLEOchar().
 *                Added xx_FLUFF constants for CGIFbound_box().
 *                Did some reorganization of CGIFbound_box().
 *  13-Jul-93 mby Added badCharList argument to CGIFbbox_IFPCLEOchar().
 *  15-Jul-93 mby Disabled CGIFkern(), width, bound_box, font_purge,
 *                segments, pcleo, & CGIFps() with Convergent Fonts.
 *  15-Jul-93 rs  Make externs for CGIFfont_purge() not be conditionalized
 *                for CACHE. Fix problem when PSEO is purged but next time
 *                through, comp_pix does not process properly by zeroing
 *                the if_state copy of the fontcontext.
 *  28-Jul-93 awr Changed CGIFchar_size() for non-zero winding
 *  02-Aug-93 maib Changed interface to prevent CGIFxxx() routines from calling
 *                other CGIFxxx() routines, required for multi-tasking. also
 *                added multicaller support code to CGIFxxx() routines
 *  03-Aug-93 maib changed definitions for cgifXXXX() routines to resolve
 *                naming conflicts
 *  13-Aug-93 mby Replaced 2 printfs in CGIFchar() with DBG1's.
 *  24-Aug-93 jfd In cgif_Font(), if symbol set is set to special encoding
 *                array value, do not call PCLeo2IF_ssnum() or SYMnew().
 *  02-Sep-93 jfd Changed function declaration for psget_FontBBox() to
 *                include both ANSI and non-ANSI formats to resolve
 *                compiler error.
 *  16-Sep-93 maib Changed CGIFchar() to support banding of alien bitmaps
 *  22-Sep-93 mby Changed cgif_Font(): to handle ROM1; do better error
 *                checking for PCLEOs. Clean up bbox code; start implementation
 *                for convergent fonts (doesn't work yet!).
 *  24-Sep-93 jfd In MULTICALLER version of CGIFenter(), if !SEM_ACCESS,
 *                if "uEnterFirstTime" is FALSE, "status" is returned as
 *                an ambiguous value. Initializing "status" to SUCCESS at 
 *                start of routine.
 *  29-Sep-93 maib Semaphore was not being released for all cases, fixed it
 *  29-Sep-93 jfd Added support for PS bounding box.
 *  30-Sep-93 mby Optimize cgif_Font() by branching around ROM1 code if font
 *                type is external.
 *                Implement CGIFwidth() for CONVERGENT_FONTS.
 *  05-Oct-93 mby Implement CGIFbound_box() for CONVERGENT_FONTS. Update
 *                IFplugin and TTplugin statics for various plugin options.
 *  08-Oct-93 jfd In CGIFchar(), if requesting a fixed space character which
 *                has already been cached, "status" is not being set to
 *                ERR_fixed_space. Check for fixed space character and
 *                set "status" to ERR_fixed_space if necessary.
 *  12-Oct-93 maib Put ansi defs around bbox_union
 *  25-Oct-93 maib Optimized cache access by placing all required CACaccess 
 *                code inline in CGIFchar
 *  26-Oct-93 mby Removed redundant code in CGIFwidth().
 *  01-Nov-93 maib Declared fcCur global for reference in instance.c
 *  05-Nov-93 mby/rk  Check get_awt_bbox() for status value.
 *  23-Nov-93 maib Added prototypes missing in multi-caller section for
 *                 fontbbox enabled functions
 *  06-Dec-93 jfd  In cgif_Font(), added calls to get_ttDISK_ids() and
 *                 get_ttROM_ids() to retrieve platform and specific IDs 
 *                 from KANJI TT font.
 *                 Including "kanji.h".
 *  14-Dec-93 mby  Set IF_FLUFF, TT_FLUFF, PS_FLUFF constants to 1 for
 *                 CGIFbound_box().
 *  04-Jan-94 jwd Modified CGIFchar_size() to return the size of the largest 
 *                compound character part, for the cc_buf_size in the IFCONFIG
 *                structure. Will be returned in size[3].
 *  05-Jan-94 jfd  In cgif_Config(), added check for bitmap width compatability
 *                 with setting of RASTER_ORG.
 *  05-Jan-94 maib Modified handling of alien bitmaps, allowing alien bitmaps
 *                 and UFST generated bitmaps to be produced at application's
 *                 discression
 *  05-Jan-94 rs   Add support for "GB" encoding.
 *  06-Jan-94 maib Fixed bug in banding alien bitmaps
 *  25-Jan-94 maib Included new cache accessing scheme for ASIAN_ENCODING
 *  27-Jan-94 mby  Minor changes in CGIFwidth() for Convergent Fonts.
 *  03-Feb-94 jfd  In CGIFsegments(), if DYNAMIC_FONTS is enabled, treat
 *                 "tfnum" argument as a pathname rather than a typeface 
 *                 number. This will allow CGIFsegments() to return segment
 *                 data without CGIFfont() having to be called.
 *  06-Mar-94 mby  Changes to CGIFbound_box() for Convergent Fonts for AWT4
 *                 format support.
 *  25-Mar-94 jfd  In CGIFwidth(), if processing CONVERGENT_FONTS, set 
 *                 "if_state.alt_width" = 0 before calling CVFget_fnt_index()
 *                 so that chwidth() will get called if there is no entry in 
 *                 the alternate width table.
 *  20-Apr-94 jfd  Changed the way CGIFsegments() interprets the "tfnum"
 *                 argument. Instead of basing it on DYNAMIC_FONTS, it now
 *                 checks for SEGACCESS = 1 or 2 as well as DYNAMIC_FONTS.
 *  25-Apr-94 mby  For font bounding bbox, changed IFplugin structure->xmax
 *                 from 8782 to 9631 to reflect new "plugin.cfp" plugin file.
 *  05-May-94 mby  In cgif_Font(), set "if_state.awtsub_on" if the awt pointer
 *                 for Convergent Fonts is set. This fixes a bug in CGIFbound_box()
 *                 where awtsub_on was not getting set, affecting the computation
 *                 of the font matrix in comp_pix() for obliqued conv. fonts.
 *                 Also fixed code in CGIFwidth() that uses awtsub_on.
 *  03-Jun-94 jfd  Changed all occurrences of ENTRY to CGENTRY to resolve
 *                 conflict on some compilers.
 *  06-Jun-94 mby  In cgif_Font() 'useMapping' = false if sym set = 0x8000.
 *                 Affects PCLETTOs with downloaded symbol set.
 *                 If useMapping is 0 call SYMnoMap().
 *  14-Jun-94 mby  For foreign bitmaps (CGIFfont) - set 'has_path' to 0;
 *                 do not call SYMnew or SYMnoMap.
 *  01-Jul-94 mby  In cgif_Font(), change call to PCLeo2IF_ssnum to use
 *                 additional argument - to fix fc->ssnum bug.
 *  12-Jul-94 jfd  In CGIFbound_box(), was not setting if_state.awtsub_on 
 *                 based on fcCur.p_AltWidTab. This was causing a problem
 *                 if switching between convergent and non-convergent fonts
 *                 for multiple threads.
 *  13-Jul-94 jfd  In CGIFwidth(), set if_state.awtsub_on based on
 *                 fcCur.p_AltWidTab to avoid potential problem that could
 *                 be caused when switching between conv. and non-conv.
 *                 fonts for multiple threads.
 *  14-Jul-94 mby  Corrections to 7-01-94 change: fcCur.ssnum = pcleo_ssnum
 *                 only if external font and useMapping are true. Also when
 *                 cgif_Font() calls SYMnew() and SYMnoMap(), the arguments
 *                 should use fcCur, not fc.
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * FCO Changes from 1.48.1.2:
 *  14-Mar-94 mby  Added FCO option to CGIFbound_box().  Added CGIFfco_Init().
 *                 In cgif_Font(), replace nonIF font test with TT || PST1;
 *                 set if_state.has_path to 0 for FCO_RDR.
 *  26-May-94 mby  Changed CGIFfco_Init() to CGIFfco_Open().
 *                 Added CGIFfco_Close(), CGIFtt_Generate(), CGIFtt_Free().
 *                 Modified CGIFenter(), CGIFexit(), CGIFbound_box().
 *                 CGIFfont() stores FCO handle in if_state.FCObject.
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *  18-Aug-94 jfd  Changed arg 2 of CGIFfco_Open() from 'int *' to
 *                 'LPSW16' due to WINDOWS.
 *  22-Aug-94 jfd  Changed args 1 and 2 of CGIFtt_Generate() ('int *'
 *                 --> 'LPSW16', 'LPUB8 *' --> 'LPLPUB8' for WINDOWS.
 *  02-Sep-94 mby  Added CGIFfco_Plugin().
 *  08-Sep-94 mby  Cleanup in CGIFwidth(), -kern() to support FCO only.
 *  11-Sep-94 jfd  Added new function CGIFhdr_font_purge().
 *  15-Sep-94 jfd  In function prototypes and function declarations for
 *                 CGIFhdr_font_purge(), changed ENTRY to CGENTRY.
 *                 Changed function prototypes for CAChdr_purge() from 
 *                 "UW16 CGENTRY" to "EXTERN UW16".
 *                 Removed function prototype for CAChdr_font().
 *                 Moved prototype for CGIFhdr_font_purge() so that it is
 *                 not conditionally compiled based on CACHE.
 *  20-Sep-94 rs   Modified CGIFinit() so that when running Windows DLL,
 *                 'CGIFinitstate' will be initialized each time (instead
 *                 of by compiler).
 *  26-Sep-94 mby  Changed CGIFfco_Open to copy int* pointer to LPSW16 pointer
 *                 before returning. Valid handles are in the range 0 - 7FFF.
 *                 If CGIFfco_Open returns an error, handle is set to 0xFFFF.
 *  06-Oct-94 mby/jfd
 *                 In cgif_Font(), set "if_state.cur_loc_fc.font_hdr = 0"
 *                 always to resolve fontcontext matching problem.
 *  11-Oct-94 SBM  In CGIFexit, added check for !FCO_RDR.
 *  18-Oct-94 mby  In CGIFbound_box() clear "chr_def_hdr.mirror_flags" to avoid
 *                 mirroring the matrix. Set "if_state.cur_loc_fc.font_id"
 *                 and ".font_hdr" to 0 to disable fontcontext matching.
 *                 Changed argument of CGIFfco_Close(), CGIFfco_Plugin()
 *                 from "int" to "SW16" for compatibility with CGIFfco_Open().
 *  20-Oct-94 mby  Changed argument of CGIFtt_Free() from "int" to "SW16".
 *  21-Oct-94 jfd  In CGIFexit(), changed the way "CGIFinitstate" is tested
 *                 based on IF_RDR to resolve memory leakage problem.
 *  14-Dec-94 rs   Changed arg 2 of CGIFtt_Generate() from LPLPUB8
 *                 to LPHPUB8.
 *  14-Dec-94 jwd  Added support for MULTICALLER in FCO related functions; 
 *                 Removed MULTICALLER dependency from CAChdr_purge 
 *                 prototype.
 *  17-Dec-94 mby/jc Fixed scale factor in CGIFbound_box() for FC_FCO_TYPE.
 *  06-Jan-95 SBM  Added new arg ttgenFlg, to CGIFtt_Generate.
 *  16-Feb-95 jfd  Corrected prototype for CGIFtt_Generate() based on
 *                 HUGE_PTR_SUPPORT.
 *  24-Mar-95 SBM  Modified CGIFtt_free to use a Ptr instead of a MEM_HANDLE.
 *  31-Mar-95 jwd  Added support for CGIFfco_Access(). Interface routine will
 *                 extract specific FCO related information based on application
 *                 needs.
 *  10-Apr-95 mby  Conditionally compiled CGIFfco_Access().
 *  18-Apr-95 jfd  In cgif_Font(), added support for the removal of
 *                 symbol set mapping.
 *                 Added new function CGIFchIdptr().
 *                 In cgif_Font(), conditionally compiled calls to SYMnew() 
 *                 and PCLeo2IF_ssnum() based on !NO_SYMSET_MAPPING.
 *  24-May-95 mby  Changed CGIFbound_box() to search FCO plugins through a
 *                 call to fco_get_FontBBox() if FCO_RDR is enabled. Fixed
 *                 division by wrong 'fScale' value.
 *                 In CGIFfco_Plugin() and CGIFfco_Close() added release_semaphor()
 *                 call before exiting.
 *                 From rk - in CGIFwidth() return width of 0x7FFF if charcode
 *                 is out of range (first_chid loop).
 *  27-Jun-95 mby  Fixed bug - CGIFbound_box(): "if_state.x.pixel_size" was
 *                 being used before call to comp_pix().
 *  13-Jul-95 mby  Conditionally compile CGIFsegments() only if IF_RDR=1.
 *  18-Jul-95 mby  In CGIFfont_purge(), CGIFhdr_font_purge(), remove code
 *                 that changes the app's fc->font_id and fc->font_hdr.
 *                 Instead, clear the fcCur copy of the fontcontext.
 *  28-Jul-95 jwd  Initialized the local sizing value lsize[3] in the 
 *                 routine CGIFchar_size(), in order to correct improper
 *                 size values being placed into members not specifically
 *                 filled by UFST/MicroType. Also added release_semaphore call
 *                 to CGIFtt_Free() before exit.
 *  02-Aug-95 mby  In CGIFbound_box(), increased FCO fluff factor to 4 in X;
 *                 to 2 in Y.
 *  04-Aug-95 jc   In CGIFfco_access(), corrected args - psize and pbuffer
 *                 (misspelling).
 *                 Changed fco y fluff from 2 to 5, because of the perthousand
 *                 character.
 *  11-Sep-95 awr  Added GRAYSCALE call to cgif_Font()
 *  14-Nov-95 rm   Removed formatting of #if
 *  22-Nov-95 mby  If (_OSK) || (_OS9000) is defined, #include <stdlib.h>
 *                 instead of <malloc.h>
 *  24-Jan-96 awr  Added compressed cache to CGIFchar().
 *  05-Feb-96 mby  In CGIFchar() release_semaphor() wasn't getting called on
 *                 return. Made same change in CGIFchar_size().
 *  06-Aug-96 mby  Fixed bug in CGIFwidth() - didn't work for ASIAN encodings
 *                 (symbol sets FFF8 - FFFF).
 *  03-Sep-96 mby  Changed 2nd arg of fco_get_FontBBox() call (in CGIFbound_box)
 *                  to [ 0 | 1 ]. We should not be passing in the scale factor.
 *                  This had caused a problem in Asian TT fonts where the font
 *                  is scaled at 256 units and the FCO/TT plugins are at 2048.
 *                 Removed "FCO_FLUFFX", "FCO_FLUFFY". Added "FCO_FLUFF".
 *                 For the Asian encodings 0xFF## (kanji.h), set
 *                  "if_state.usePlugins = FALSE" in CGIFfont().
 *  17-Sep-96 mby  In bbox_union(), return immediately if plug->emRes is 0 -
 *                 to fix ?by 0 error.
 *  01-Oct-96 jfd  Implemented new ASIAN cache architecture.
 *                 In CGIFexit(), calling ASIANexit() to free pointers
 *                 to ASIAN mapping tables as part of shutdown.
 *  16-Oct-96 jfd  In CGIFchar(), when checking for space character,
 *                 test if processing bitmap or outline.
 *  06-Nov-96 mby  Added new API call CGIFfont_metrics().
 *  07-Nov-96 mby  Fixed bug in CGIFchar(), grayscaled space chars were not
 *                 returning ERR_fixed_space.
 *  14-Nov-96 mby  For ASIAN_ENCODING, enable plugins in cgif_Font() [undo
 *                 change 9/3/96 ]
 *  18-Nov-96 mby  Clean up CGIFfont_metrics().
 *  01-Jan-97 dlk  In CGIFexit(), added BIG5_ENCODING and GB_ENCODING to
 *                 conditional of calling ASIANexit() to free pointers to
 *                 Asian Mapping Tables as part of shutdown.
 *                 Added 'langID' argument to calls to get_ttDISK_ids and
 *                 get_ttROM_ids for distinguishing between GB and BIG5 encoded
 *                 Asian fonts.
 *  08-Jan-97 dlk  Deleted KERN option as part of project to trim ufst.
 *  09-Jan-97 dlk  Put TRACK_KERN_KEY, TEXT_KERN_KEY, and DESIGN_KERN_KEY back
 *                 in to case statement - for now.
 *  13-Jan-97 dlk  Removed CONVERGENT_FONTS option as part of project to trim
 *                 ufst.
 *  14-Jan-97 dlk  Removed MULTIFORMAT option as part of project to trim ufst.
 *  15-Jan-97 dlk  Removed PST1_PCLEOI option as part of project to trim ufst.
 *  18-Mar-97 mby  In CGIFfont() if GRAYSCALING is on, always call grayfont().
 *                 CGIFexit() calls grayexit() for cleanup.
 *  25-Mar-97 dlk  Added check_galley() function, and calls to it in CGIFchar()
 *                 and cgif_Char_Handle() to support Galley Character Segment
 *                 processing (when chId isn't found in the current font &
 *                 GalleyFlags field in fontcontext is set ON).  Added new
 *                 function size_check_galley(), and a call to it in CGIFchar_
 *                 size() to support Galley Character Segment processing.
 *  25-Mar-97 dlk  Added prototypes for check_galley() and size_check_galley().
 *  25-Mar-97 dlk  Corrected reference to CHAR, which should have been CACHE.
 *  27-Mar-97 slg  Fix bad cast in get_ttROM_ids() call (TT_ROM/ASIAN_ENCODING)
 *  03-Apr-97 mby  Fix CGIFbound_box() if grayscale P alignment is on. It
 *                 returned values that were too big.
 *  07-Apr-97 jfd  Changed return type of check_galley() function declaration
 *                 to MLOCAL to match prototype definition.
 *  17-Apr-97 dlk  Removed all Galley Character Segment processing support that
 *                 had been added recently.  This capability will be moved to
 *                 'ttset_char()' in 'tt_if.c'.
 *  08-May-97 mby  Added check for error in CGIFfont_metrics().
 *  29-May-97 sbm  Add TT_ROM_ACT functionality.
 *  04-Jun-97 dlk  Added WANSUNG and JOHAB Korean support to cgif_Font.
 *                 Also added a new 1st parameter (UW16) for passing the cur-
 *                 rent ssnum to get_ttDISK_ids() and get_ttROM_ids() - for
 *                 support of matching requested encoding to cmap tables in
 *                 TrueType fonts.
 *  16-Jun-97 awr  Fixed compiler warning in CGIFfcoOpen() and conditionally
 *                 compiled tiling code on CGBITMAP in additioni to TILE.
 *  16-Jun-97 slg  Add char* cast to fix "SIGNEDCHAR NO" compile
 *  31-Jul-97 sbm  Moved FC_ACT_TYPE to ExtndFlags, now EF_ACT_TYPE.
 *  14-Aug-97 sbm  In cgif_Font, test if rom_thing = ENTITYACT before calling get_ttROMACT_ids,
 *                 else call get_ttROM_ids.
 *  21-Aug-97 jfd  In cgif_Font(), after calling get_ttROM...ids(), check
 *                 return value for possible error.
 *  03-Sep-97 jfd  The following changes were made to resolve the PS
 *                 banding/space char problem:
 *                 In cgif_Tile(), if bitmap_tile() returns an "invalid_tile"
 *                 error, return the dereferenced handle to the caller.
 *                 In CGIFchar(), if cgif_Tile() returns an "invalid_tile" 
 *                 error, store the escapement and em box sizes in the 
 *                 IFBITMAP structure.
 *  03-Sep-97 slg  In cgif_Config(), paths are irrelevant if ROM (spacesaving)
 *  06-Sep-97 mby  In CGIFfont_metrics(), changed "act" back to "mtx"
 *                 - global search & replace changed stuff it shouldn't have.
 *  14-Sep-97 jwd  Repaired compiler error, occuring if GRASCALING and CHAR_SIZE
 *                 are both enabled. Data item fcCur needs to be passed as ptr to
 *                 FC_ISGRAY macro.
 *  16-Sep-97 slg  Fix compile for ARM/Helios
 *  21-Nov-97 mby  Call to fco_saveHndl() in CGIFfco_Plugin() is conditional
 *                 on #if PLUGINS
 *  21-Jan-98 dlk  Added #if ASIAN_ENCODING conditional to code calling the
 *                 ASIANexit() routine - this eliminates compiler warnings.
 *  29-Jan-98 keb  Makechar() is conditionally defined based on CACHE or CHAR_HANDLE
 *  26-Jan-98 awr  Added pointer to if_state as argument to comp_pix() in
 *                 CGIFbound_box()
 *  30-Jan-98 slg  Some IFCONFIG fields are DISK-only; delete code for obsolete
 *                 TT plugin options
 *     10-Feb-98 slg  Add a few DBG() stmts that would have been useful last week
 *   7-Feb-98 awr  Removed CGIFbound_box() prototypes since they are already
 *                 in cgif.h. Added VLC support for CGIFbound_box()
 *  02-Mar-98 dah  Added ASIANVERT code
 *  27-Mar-98 jfd  In CGIFchar(), added a check to return an error code
 *                 if banding is specifed with a scaling matrix other
 *                 than Typographer.
 *                 In same function, conditionally compiled check of
 *                 rotation angle for cases of !SCALE_MATRIX and
 *                 TYPE_SCALE_MATRIX.
 *  31-Mar-98 slg  Add init_former_globals() function (called from CGIFinit()
 *                   to initialize former globals/MLOCALs. Also make seemingly-
 *                   useless MLOCAL pathname a local dynamic vbl.
 *    01-Apr-98 slg  Move GLOBAL CGIFinitstate into IF_STATE.
 *    02-Apr-98 slg  Move GLOBALs cc_buf, cc_size, fcCur into IF_STATE.
 *  11-Apr-98 awr  Moved the very useful MLOCAL pathname to IF_STATE to fix
 *                 disk font input.
 *  14-Apr-98 slg  Set if_state.special_case in init_former_globals()
 *  11-May-98 keb  removed condition which included 'ttroment.h' based on 
 *                 TT_ROM_ACT being enabled
 *  26-May-98 slg  Set if_state vbls moved from /psi in init_former_globals().
 *    15-Jun-98 slg  Get rid of MULTICALLER / SEM_ACCESS code; merge some now-
 *                   superfluous functions (for example, cgif_Font and CGIFfont);
 *                   add parameter-passing changes for reentrancy
 *   6-Aug-98 awr  Changed !ROM to DISK_FONTS
 *  17-Aug-98 awr  Fixed CGIFps(), got broken with some of the recent changes
 *  25-Aug-98 jwd  Repaired CGIFbound_box function declaration; error encountered 
 *                 on SPARC system due to extra declaration.
 *  15-Oct-98 ks   Conditionally compile ref. to SYMnoMap to ((PCLEO_RDR || TT_ROM1) && NO_SYMSET_MAPPING).
 *                       Fixes compile bug \rts\da\symmap.c error SYMBOLSET_IF undeclared ident. when FCO_DISK is enabled.
 *  08-Dec-98 jwd  Restored conditional compile of call to SYMnoMap(). Routine was
 *                 modified to fix compile error.
 *  18-Feb-99 ks   Fix IF plugin problem with NO_SYMSET_MAPPING enabled.  Modified
 *                   CGIFfont() to only set if_state.usePlugins to FALSE for external
 *                   softfonts with NO_SYMSET_MAPPING.
 *  10-Mar-99 dlk  In CGIFwidths(), for CFF processing, added conditional call
 *                 to set up character environment BEFORE attempting access to
 *                 width information via chwidth()... psget_width()..., and
 *                 finally type2char().
 *  25-Mar-99 keb  Conditionally compile PSEUDO_HALF_WIDTH code
 *  21-Jun-99 jfd  In CGIFfont(), no longer calling get_tt...() functions
 *                 to retrieve platform and specific IDs. This is now
 *                 done in the ttload...() functions.
 *  28-July-99 ks  Changed DEBUG compiler directive to AGFADEBUG. 
 *  23-Aug-99  ks  Remove bucket created in CGIFsegments.  Bucket can't be created here...all global
 *                   variables may not be initialized yet.  Problem when it's called before CGIFfont().
 *    July-99 swp  code to compute fc->lpm -- needed for new quadvectorize. enabled if SWP799 is defined
 *    10-Nov-99 slg  Replaced FCcopy() call in CGIFfont() by "memcpy" call.
 *    18-Jan-00 slg  Vertical-writing changes (for keb): initialize 
 *                   "have_adjusted_angle"; fixes in #if-PSEUDO_HALF_WIDTH case;
 *                   use PS rather than SS in PSEUDO_HALF_WIDTH case. Also:
 *                   compile fixes in CGIFfont() (for SWP799 and SCALE_MATRIX).
 *    31-Jan-00 slg  Integrate disk/rom changes (for jd) - add CGIFfont_access();
 *                   modify setting of "has_path" in CGIFfont(), 
 *                   initialize "font_access" in init_former_globals().
 *  03-Feb-00 slg  Simultaneous disk/rom now always in effect: set default
 *                   value of "font_access" to match current build (ROM if both)
 *  03-Feb-00 awr  Changed SWP799 to WINDCOMP
 *  24-Mar-00 jwd  Cache w/ NO_SYMSET_MAPPING fix.
 *  19-Apr-00 jfd  In CGIFfont(), store 'lpm' in 'if_state.fcCur.lpm',
 *  28-Sep-00 jfd  In CGIFfont(), calculate 'xlpm' and 'ylpm' instead of
 *                 just 'lpm' and remove conditional compile based on
 *                 WINDCOMP.
 *    05-Dec-00 slg  Add CGIFtt_cmap_query() function = specialized TT query function
 *                    which returns a list of all the cmap tables in a TT font.
 * 24-Aug-01 jfd / jwd PCLEO changes.
 * 04-Sep-01 jfd  NOSYMSET / CACHE / PS bug fix:
 *                In CGIFchar(), retrieve chId from chIdptr if NOSYMSET.
 *                In CGIFchIdptr(), map charname to cg number if PS.
 * 05-Dec-01 jfd  In CGIFfont(), added check for valid stroke percent if processing
 *                a stick font.
 * 23-Jan-02 jfd  In CGIFfont(), if stroke percent is not supplied (== 0), set to
 *                default value of 3%.
 * 28-Mar-02 jfd  In CGIFfont(), if unbound pcleo, set "usePlugins" to TRUE.
 * 27-Aug-02 swp Added fix for rotated stroke fonts with MAT0.
 * 10-Sep-02 jfd    In CGIFfont(), set "if_state.lpm" to "fc->ylpm" for !SCALE_MATRIX and for
 *                       TYPO_SCALE_MATRIX.
 * 15-Aug-02 awr  Added DIMM_DISK
 * 25-Sep-02  jfd   In CGIFbmheader(), if MAKifbmheader() returns ERR_reflines_needed, call
 *                        extract_reflines() for "HOxo" metrics which are needed by autohint_stik().
 * 23-Oct-02  jfd    In CGIFfont(), removed code which calculated "lpm", "xlpm" and "ylpm"
 *                         (moved to matrix_to_scale()).
 *  04-Nov-02 jfd  In CGIFwidth(), free handle after calling CGIFchar_handle().
 *  07-Jan-03 jfd  In CGIFbmheader(), fixed "hanging" problem when switching from
 *                 plugins to STIK fonts.
 *  12-Jun-03 jfd  Added "cache-by-reference" support.
 *  13-Aug-03 jfd  Added "table-by-reference" support.
 *  20-Aug-03 jfd  Left out part of cleanup in CGIFtt_query_direct_free().
 *  19-Sep-03 jfd  Moved test for chId > 0xffff from CGIFchar(), CGIFchar_handle() and CGIFchar_size()
 *                 to MAKifbmheader() so that linked fonts will process correctly.
 *  23-Sep-03 jfd  In CGIFfont(), moved test for linked fonts before test for Intellifont to resolve
 *                 error when processing linked fonts with Intellifont disabled.
 *  03-Oct-03 awr  Changed CGIFfont() to set the 1st font in a linked font
 */

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

#include <stdio.h>
#include <string.h>
#include "cgconfig.h"

#include "ufstport.h"

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

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

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

#include "dbg_ufst.h"

#include "shareinc.h"

#include "fontmath.h"

#if TT_RDR
#include "sfntenum.h"
#endif

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

#include <stdlib.h>

#if MAYBE_MALLOC_H
#include <malloc.h>
#endif
extern LPUB8 rom_LoadTT( LPUB8 );


#if TT_ROM_ACT
#include "config.h"
#include "ra_mem.h"
#include "bitio.h"
#include "radecomp.h"
#endif

#if PCLEO_RDR
#define GET_LONG( destp, srcp )   MEMCPY( (SB8 *)(destp), (SB8 *)(srcp), 4 );
#define GET_WORD( destp, srcp )   MEMCPY( (SB8 *)(destp), (SB8 *)(srcp), 2 );
#endif /* PCLEO_RDR */

#ifdef LINT_ARGS
#if FONTBBOX
#if IF_PCLEOI
      MLOCAL VOID bbox_SimpleChar( LPUB8, LPSW16, LPSW16, LPSW16, LPSW16 );
#endif  /* IF_PCLEOI */
#endif  /* FONTBBOX */

#if (PST1_RDR && FONTBBOX)
MLOCAL UW16  psget_FontBBox( PBUCKET, BBoxRes* );
#endif

#else   /*  not LINTARGS  */

#if FONTBBOX
#if IF_PCLEOI
MLOCAL VOID bbox_SimpleChar();
#endif  /* IF_PCLEOI */
#endif  /* FONTBBOX  */

#if (PST1_RDR && FONTBBOX)
MLOCAL UW16  psget_FontBBox();
#endif
#endif /* LINT_ARGS */


#if defined (ANSI_DEFS)
GLOBAL VOID init_former_globals(FSP0)    /* 06-28-04 jfd */
#else
GLOBAL VOID init_former_globals()        /* 06-28-04 jfd */
#endif /* ANSI_DEFS */
{
    MEMSET (&if_state, '\0', sizeof (IF_STATE));

/* For reentrancy, all former read/write globals and MLOCALs will be moved
into IF_STATE structure. All such vbls that were initialized when declared
should now be initialized in this function. (sandra, 30 Mar '98)    */

#if CACHE
    if_state.CGIFinitstate = not_buf | not_cac | not_intellifont;
#else
    if_state.CGIFinitstate = not_buf | not_intellifont;
#endif

#if FCO_RDR
#if FCOACCESS
    if_state.size_computed = FALSE;
#endif
#endif    /* FCO_RDR */

#if GRAYSCALING
    if_state.bs_gm.maxbytestream = 0;
    if_state.bs_gm.bitbuf = 0;
    if_state.bs_gm.bitct = 0;
    if_state.bs_gm.numused = 0;
    if_state.bs_gm.bytestream = 0;
    if_state.bs_gm.p_bytestream = 0;
    if_state.gs_count = 0;
#if UFST_MULTITHREAD
    if_state.charBuf = NULL;
    if_state.charBufSize = 0;
#endif
#endif    /* GRAYSCALING */

#if DISK_FONTS
    if_state.ufstPath[0] = 0;
    if_state.typePath[0] = 0;
#endif    /* DISK_FONTS */

#if IF_RDR || PST1_RDR
    if_state.hchar_buf = NIL_MH;
#endif

#if IF_RDR
#if SLIM_FONTS && (CGBITMAP || LINEAR || QUADRA || GRAYSCALING)
    if_state.special_case = 0;
#endif

/*** comment copied from /cor/manipula.c ***/
/* dET initialize the variables "x_tran, y_tran".  This is a trick to force 
       the variables into the data segment rather than the BSS segment.
       NOTE the changes in "imath.asm"
*/
/** GLOBAL TRAN x_tran = {1,0}, y_tran = {1,0};      **/
    if_state.x_tran.num = 1;
    if_state.x_tran.den = 0;
    if_state.y_tran.num = 1;
    if_state.y_tran.den = 0;
#endif    /* IF_RDR */

#if PST1_RDR   
    if_state.scanning_proc = 0;
#if PS_ERRORCHECK
    if_state.t1_stacklimit = if_state.args + T1ARGSTACKSIZE;
#endif 
#endif    /* PST1_RDR */  

/* keb 7/99 */
    if_state.have_adjusted_angle = 2;  /* 1 if we have changed things do to adjust_angle
                                            being 1, 0 otherwise, 2 initially */

/* If only one of (ROM, DISK_FONTS) is enabled, default will be set correctly. */
/* If both are enabled, ROM will be default: use CGIFfont_access to change. */
#if DISK_FONTS
    if_state.font_access = DISK_ACCESS;
#endif
#if ROM
    if_state.font_access = ROM_ACCESS;
#endif

#if DIRECT_TT_TABLE_ACCESS
    if_state.hdatables = (MEM_HANDLE)NIL_MH;
    if_state.datables = NULL;
#endif

#if PCLEO_RDR    /* demo code for PCLEO processing */
    init_pcleo_callback_data( FSA0 );
#endif

}


/* function for testing on the basic typedefs */
#if defined (ANSI_DEFS)
static UW16 check_types(FSP0)
#else
static UW16 check_types()
#endif /* ANSI_DEFS */                
{
    SB8        s8;        
    UB8        u8;        
    SW16    s16;        
    UW16    u16;        
    SL32    s32;    
    UL32    u32;    

    
#if (SIZEOF_LONG == 8)
    SL64    s64;    /* signed 64 bit */
    UL64    u64;    /* unsigned 64 bit */
#endif
     
#if defined(UFST_MULTITHREAD) && !defined(UFST_REENTRANT)        
    {        
        DBG("MULTITHREAD requires REENTRANT\n");        
        return ERR_MULTI_REENTRANT;        
    }
#endif

    /* ------------ byte order checking ------------ */        
    {
#if INTLENGTH == 16
            int s;
#elif INTLENGTH == 32            
#if defined (PTV_OS)
            signed short s;
#else
            short s;
#endif
#endif
            
#if SIGNEDCHAR == YES                    
            char    *p;        
#else
            signed char  *p;        
#endif        
            
            s = 1;        
            p = (char *)&s;        
            if (p[0] == 1 && BYTEORDER == HILO)            
            {
                DBG("BYTE_ORDER is set incorrectly\n");        
                return ERR_BYTE_ORDER;        
            }
    }    
        
    /* ------------ 8 bit integer ------------ */
    /* signed */
    s8 = (SB8)(-1);
    if ( 1 != sizeof(SB8) || s8 != -1 )
    {
        DBG("SB8 not a signed 8 bit integer\n");
        return ERR_SB8_TYPE;
    }
        
    s8 = (SB8)0x7F;
    s8++;
    if (s8 > 0)
    {
        DBG("SB8 not a signed 8 bit integer\n");
        return ERR_SB8_TYPE;
    }

    s8 = 0;
    s8--;
    if (s8 > 0)
    {
        DBG("SB8 not a signed 8 bit integer\n");
        return ERR_SB8_TYPE;
    }

    /* unsigned  */    
    u8 = (UB8)(-1);
    if (1 != sizeof(UB8) || u8 != 0xFF)
    {
        DBG("UB8 not an unsigned 8 bit integer\n");
        return ERR_UB8_TYPE;
    }

    u8 = 0xFF;
    u8++;
    if (u8 != 0)
    {
        DBG("UB8 not an unsigned 8 bit integer\n");
        return ERR_UB8_TYPE;
    }


    /* ------------ 16 bit integer ------------ */
    /* signed */
    s16 = (SW16)(-1);
    if (2 != sizeof(SW16) || s16 != -1)
    {
        DBG("SW16 not a signed 16 bit integer\n");
        return ERR_SW16_TYPE;
    }
        
    s16 = 0x7FFF;
    s16++;
    if (s16 > 0)
    {
        DBG("SW16 not a signed 16 bit integer\n");
        return ERR_SW16_TYPE;
    }
    
    s16 = 0;
    s16--;
    if (s16 > 0)
    {
        DBG("SW16 not a signed 16 bit integer\n");
        return ERR_SW16_TYPE;
    }

    /* unsigned */
    u16 = (UW16)(-1);
    if (2 != sizeof(UW16) || u16 != 0xFFFF)
    {
        DBG("UW16 not an unsigned 16 bit integer\n");
        return ERR_UW16_TYPE;
    }


    /* ------------ 32 bit integer ------------ */
    /* signed */
    s32 =  (SL32)(-1);
    if (4 != sizeof(SL32) || s32 != -1)
    {
        DBG("SL32 not a signed 32 bit integer\n");
        return ERR_SL32_TYPE;
    }

    s32 = 0x7FFFFFFFL;
    s32++;
    if (s32 > 0)
    {
        DBG("SL32 not a signed 32 bit integer\n");
        return ERR_SL32_TYPE;
    }
    
    s32 = 0;
    s32--;
    if (s32 > 0)
    {
        DBG("SL32 not a signed 32 bit integer\n");
        return ERR_SL32_TYPE;
    }

    /* unsigned */
    u32 = (UL32)(-1);
    if (4 != sizeof(UL32) || u32 != 0xFFFFFFFFUL)
    {
        DBG("UL32 not an unsigned 32 bit integer\n");
        return ERR_UL32_TYPE;
    }

    /* ------------ 64 bit integer ------------ */
#if (SIZEOF_LONG == 8)
    /* signed */
    s64 =  (SL64)(-1);
    if (8 != sizeof(SL64) || s64 != -1)
    {
        DBG("SL64 not an signed 64 bit integer\n");
        return ERR_SL64_TYPE;
    }

    s64 = 0x7FFFFFFFFFFFFFFF;
    s64++;
    if (s64 > 0)
    {
        DBG("SL64 not an signed 64 bit integer\n");
        return ERR_SL64_TYPE;
    }
    
    s64 = 0;
    s64--;
    if (s64 > 0)
    {
        DBG("SL64 not an signed 64 bit integer\n");
        return ERR_SL64_TYPE;
    }

    /* unsigned */
    u64 = (UL64)(-1);
    if (8 != sizeof(UL64) || u64 != 0xFFFFFFFFFFFFFFFF)
    {
        DBG("UL64 not an signed 64 bit integer\n");
        return ERR_UL64_TYPE;
    }


#endif

#if (SIZEOF_LONG == 8)
        
    if (sizeof(unsigned long) != SIZEOF_LONG)
    {
        DBG("SIZEOF_LONG != sizeof(unsigned long)\n");
        return ERR_SIZEOF_LONG;
    }
#elif INTLENGTH == 16
    if (sizeof(unsigned long) != SIZEOF_LONG)
    {
        DBG("SIZEOF_LONG != sizeof(unsigned long)\n");
        return ERR_SIZEOF_LONG;
    }    
#elif INTLENGTH == 32    
    if (sizeof(unsigned int) != SIZEOF_LONG)        
    {
        DBG("SIZEOF_LONG != sizeof(unsigned int)\n");
        return ERR_SIZEOF_LONG;
    }
#endif

    /* if HAS_FS_INT64 is defined ... see if it really works */
#ifdef HAS_FS_INT64        
    {
        FS_INT64 a, b, c, d;

        a = 12345678;
        b = 87654321;
        a += b;
        c = a*b;
        d = c/b;

        if (d != a)
        {
            DBG("FS_INT64 code doesn't seem to work\n");
            return ERR_INT_64;
        }    
    }
#endif /* HAS_FS_INT64 */

        return SUCCESS;    
}


/*----------------*/
/*  CGIFinit      */
/*----------------*/
/*
This function initializes the memory manager.
*/

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFinit(FSP0)
#else
UW16 CGENTRY
CGIFFinit()
#endif /* ANSI_DEFS */
{
    UW16     status = 0;
    status = check_types(FSA0);        /* check type */

    if (status)
       return (status);
    init_former_globals(FSA0);

    status = MTinit(FSA0);            /* Initialize multi-thread manager */
    if (status)
        return status;

    MEMinit(FSA0);                /* Initialize memory manager   */
    return SUCCESS;
}


/*----------------*/
/*  CGIFconfig    */
/*----------------*/
/*  The application calls this function to set or change the
 *  configuration parameters.
*/

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFconfig (FSP PIFCONFIG cfg)
#else
UW16 CGENTRY
CGIFconfig(cfg)
    PIFCONFIG cfg;
#endif /* ANSI_DEFS */
{
  /*  Set configuration values  */
#if DISK_FONTS
    if_state.max_open_files = cfg->num_files;  /* max number of open library files */
#endif
    if_state.bit_map_width = cfg->bit_map_width;  /* bmap alignmnt bytes */

    if(if_state.bit_map_width < (UW16)RASTER_ORG)
        return ERR_incomp_bitmap_width;  /* conflict with RASTER_ORG */

    if(if_state.bit_map_width > 4)
        return ERR_bad_bitmap_width;
    if_state.bit_map_width <<= 3;                             /* Convert to pixels */

#if DISK_FONTS
    if(STRLEN((FILECHAR *)if_state.ufstPath) <= 1)               /* cannot change if_state.ufstPath */
        STRCPY((FILECHAR *)if_state.ufstPath, (FILECHAR *)cfg->ufstPath);
    STRCPY((FILECHAR *)if_state.typePath, (FILECHAR *)cfg->typePath);
#endif

#if CACHE
    if_state.max_char_size = cfg->max_char_size; /* max cached character IFBITMAP size */
#endif

#if CHAR_SIZE
    if_state.cc_buf  = cfg->cc_buf_ptr;                /* compund character buffer */
    if_state.cc_size = cfg->cc_buf_size;
#endif
    return SUCCESS;
}


/*-----------------------*/
/*    CGIFFenter         */
/*-----------------------*/
/*  This function is called once after the memory pools have been funded
 *  to initialize the cache and the font management subsystem.

 * Read PostScript mapping table into memory if PS is enabled. - 5/21/92 - rs
 */

#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFenter (FSP0)
#else
UW16  CGENTRY
CGIFFenter()
#endif /* ANSI_DEFS */
{
    UW16 status;

    status = IXinit(FSA0);         /* buffers, font index, and symbol set */
    if (status)
       return status;

#if CACHE
    status = CACinit(FSA0);
    if (status) {
      IXexit(FSA0);
      return (status);
    }
#endif

#if FCO_RDR
    status = FCOinit(FSA0);
    if (status)
    {
#if CACHE
      CACexit(FSA0);
#endif
      IXexit(FSA0);
    }
#endif

    return (status);
}


/*-----------------------*/
/*    CGIFFexit          */
/*-----------------------*/

#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFexit (FSP0)
#else
UW16  CGENTRY
CGIFFexit()
#endif /* ANSI_DEFS */
{
    DBG("CGIFexit()\n");

#if IF_RDR
    if(if_state.CGIFinitstate) return SUCCESS;      /* not initialized */
#else
    if(if_state.CGIFinitstate & ~not_intellifont) return SUCCESS;      /* not initialized */
#endif

#if (PST1_RDR || TT_RDR) && ASIAN_ENCODING
#if ((UNICODE_IN || (UNICODE_MAPPING & JIS2UNI_MAP) \
                 || (UNICODE_MAPPING & KSC2UNI_MAP) \
                 || (UNICODE_MAPPING & BIG52UNI_MAP)\
                 || (UNICODE_MAPPING & GB2UNI_MAP) ) && DISK_FONTS)
    ASIANexit(FSA0);
#endif
#endif /* ASIAN_ENCODING */

#if GRAYSCALING
    grayexit(FSA0);
#endif

#if FCO_RDR
    FCOexit(FSA0);
#endif

#if CACHE
    CACexit(FSA0);
#endif

    IXexit(FSA0);

    return SUCCESS;

} /* CGIFexit() */


/* ------------------------------- CGIFFfont -------------------------------
 *
 * Description: The application calls this function when the current font-
 *              context changes.
 * Parameters:  fc - pointer to FONTCONTEXT structure.
 * Returns:     UW16 status code ( 0 = SUCCESS, nonzero = error )
 *
 */
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfont (FSP PFONTCONTEXT fc)
#else
UW16 CGENTRY CGIFFfont (fc)
    PFONTCONTEXT  fc;
#endif /* ANSI_DEFS */
{
    UW16 status = SUCCESS;
#if LINKED_FONT
    FONTCONTEXT member_fontcontext;
#endif

    BOOLEAN useMapping;     /* if high bit set or if ENTITY1 type (mby 9-93) */
#if PCLEO_RDR
    UW16 pcleo_sscode=0;      /* mby, 07-01-94 */
#endif

    DBG("CGIFfont\n");

#if LINKED_FONT
    if  ( FC_ISLINKEDFONT(fc) )
    {
        LINKED_FNT* lfnt;
        if (fc->font_hdr && !MEMCMP("LINKED FONT", (LPSB8)fc->font_hdr, 11) )
        {
            MEMCPY(&if_state.fcLinkedFont,fc,sizeof(FONTCONTEXT));
            lfnt = (LINKED_FNT*)(if_state.fcLinkedFont.font_hdr);
            if ( lfnt->ft_counter > MAX_FONT_NUM )
            {
                status = ERR_too_many_fonts;
                return status;
            }    
            fc = &member_fontcontext; /* so that regular font context processing (below) works */
            LFNT_SetFONTCONTEXT(FSA fc, 0); /* set to first font */
            /* Fall through to execute CGIFfont() on this new member FONTCONTEXT */
        }
    }
#endif
    if( FC_ISIF( fc ) && (if_state.CGIFinitstate & not_intellifont) )
        return ERR_no_font_index;

    if_state.usePlugins = TRUE;

#if STIK && (TT_DISK || TT_ROM || TT_ROM_ACT)    /* 12-01-01 jfd */
    /* If no stroke percent is supplied, store a default stroke percent of 3% */
    if (fc->stroke_pct == 0x00000000)
        fc->stroke_pct = 0x000007AE;    /* 3% */

    if (fc->stroke_pct < 0x00000100 || fc->stroke_pct > 0x00002000)
        return ERR_stroke_pct;
#endif    /* STIK && (TT_DISK || TT_ROM || TT_ROM_ACT) */

#if PCLEO_RDR    /* 08-06-01 jfd */

    /* Initialize the PCLExxO technology type being processed to scalable */
    /* fonts. jwd, 07/21/03.                                              */

    if_state.PCL_FSTTechnology = PCL_SCALABLE_FONT;
    if_state.DLBmpInProcess    = FALSE;

    if( FC_ISEXTERN( fc ) )
    {
        if_state.PCL_font_type = (fc->font_hdr[SS_ORG] == 0 || fc->font_hdr[SS_ORG] == 1
            || fc->font_hdr[SS_ORG] == 2) ? PCL_BOUND_FONT : PCL_UNBOUND_FONT;
    
    
        /* Check for FST Technology, in download font. jwd, 07/21/03.  */
        /* In XL fonts, let's use byte 70, the Font Scaling Technology */
        /* field; in older PCL (non-XL data), we use the format field. */

        if (FC_ISXLFONT(fc))
           if_state.PCL_FSTTechnology = (fc->font_hdr[PTO_FST] == 1)
              ? PCL_SCALABLE_FONT : PCL_BITMAP_FONT;
        else
           if_state.PCL_FSTTechnology = (fc->font_hdr[DESC_FORMAT] == 0 || fc->font_hdr[DESC_FORMAT] == 20) 
              ? PCL_BITMAP_FONT : PCL_SCALABLE_FONT;

        if (if_state.PCL_FSTTechnology == PCL_BITMAP_FONT)
           if_state.DLBmpInProcess = TRUE;
    
    }
#endif            /* 08-06-01 jfd */

    useMapping = ( (fc->ssnum != DL_SYMSET) && FC_SSMAP(fc))
#if PCLEO_RDR    /* 08-06-01 jfd */
        && ( (FC_ISEXTERN(fc) && (if_state.PCL_font_type == PCL_BOUND_FONT))
        ||   !FC_ISEXTERN(fc) )
#endif            /* 08-06-01 jfd */
        ;

#if TT_RDR
    if ( FC_NO_SSMAP(fc) && FC_ISTT(fc) )
    {
       if_state.symbolset.tt_platID = (UW16)(fc->dl_ssnum & 0x000F);
       if_state.symbolset.tt_specID = (UW16)(fc->dl_ssnum & 0x00F0) >> 4;
    }
#endif  /* TT_RDR */

#if PCLEO_RDR
    /* font_id is in pcleo font hdr, so set it in fontcontext for later use. */
    if( FC_ISEXTERN( fc ) )
    {
       UW16 pcleo_ssnum;

       if( FC_ISIF( fc ) )
       {
#if IF_PCLEOI
          GET_LONG(&fc->font_id, fc->font_hdr + FONT_NUMBER);
          GET_WORD(&pcleo_ssnum, fc->font_hdr + SS_CODE );
#else
          return ERR_fst_type;
#endif
       }

     /* TrueType & PostScript PCLExO header data is always in Motorola
      * byte order (hi-lo). Use GET_xLONG(), GET_xWORD() macros.
      */
       else
       {
    /* check for bad fst type */
#if !(PST1_SFNTI)
          if (FC_ISPST1(fc))
              return ERR_fst_type;
#endif
#if !TT_PCLEOI
          if (FC_ISTT(fc))
              return ERR_fst_type;
#endif

#if (TT_PCLEOI || PST1_SFNTI)
          fc->font_id = GET_xLONG_OFF(fc->font_hdr, FONT_NUMBER);
          pcleo_ssnum = GET_xWORD_OFF(fc->font_hdr, SS_CODE );
#endif
       }

       fc->font_id &= PCLFONT_NUMBER_MASK;  /* grab only significant bytes */
       if (useMapping)
       {        /* convert to IF ssnum and save in fontcontext -ss 7/29/92 */
          status = PCLeo2IF_ssnum( FSA fc, pcleo_ssnum, &pcleo_sscode );
          if (status)
             return status;
       }

       if (FC_SSMAP(fc) && (if_state.PCL_font_type == PCL_UNBOUND_FONT))
           pcleo_sscode = (UW16)PCL_UNBOUND_FONT_SS;

    }       /* if ( FC_ISEXTERN(fc) ) */
#endif  /* PCLEO_RDR */

    /* ks - 02/18/99 Fix IF plugin problem with NO_SYMSET_MAPPING enabled.
    Only set if_state.usePlugins to FALSE for external softfonts with NO_SYMSET_MAPPING, or
    when the user has requested processing of a downloaded symbol set
    */

#if PCLEO_RDR    /* 10-17-03 jfd, jwd */

    /* The following case has been tweaked to properly handle a bound font */
    /* that is downloaded with a symbol set that does not exist in the .ss */
    /* files. In this case, we want to process the same way as if ssnum is */
    /* set to DL_SYMSET.  The fringe case is access to plugin data,  which */
    /* should still be available by UNICODE access (if the OEM has set the */
    /* API up to handle). Please see jwd for questions. jwd, 07/15/03.     */
    if (FC_ISEXTERN(fc))
    {
        useMapping =    !( fc->ssnum == DL_SYMSET ||
                           fc->ssnum == UNICODE ||
                           !pcleo_sscode ||
                           pcleo_sscode == (UW16)PCL_UNBOUND_FONT_SS
                         );

        if (!pcleo_sscode || fc->ssnum == DL_SYMSET)
            if_state.usePlugins = FALSE;
    }
#endif    /* 10-17-03 jfd, jwd */

    if( FC_NO_SSMAP(fc) && FC_ISEXTERN(fc) )
        if_state.usePlugins = FALSE;

#if (PST1_RDR || TT_RDR)
    /* for PS and TT fonts, reset the font id of the fontcontext to
     * prevent problems which may occur when switching between FST's
     */
    if ( (FC_ISTT( fc ) || FC_ISPST1( fc )) && !FC_ISEXTERN( fc ))
       fc->font_id = 0;

#endif  /* (PST1_RDR || TT_RDR) */

    MEMCPY(&if_state.fcCur,fc,sizeof(FONTCONTEXT));

#if GRAYSCALING
    if ((status = grayfont(FSA &if_state.fcCur)) != SUCCESS)
        return status;
#endif

#if PCLEO_RDR
    if( FC_ISEXTERN( fc ) && useMapping )   /* mby 07-14-94 */
        if_state.fcCur.ssnum = pcleo_sscode;
#endif

#if CACHE
    status = CACfont(FSA &if_state.fcCur);   /* Inform cache of new font */
    if (status)
       return status;
#endif

#if DISK_FONTS
    if (FC_ISROM(fc) || FC_ISFCO(fc))  
       if_state.has_path = FALSE;
    else
       if_state.has_path = (!FC_ISEXTERN(fc) && !fc->font_id);  /* PS, TT disk, IF dyn */

#if DIMM_DISK
    if(FC_ISDIMM_DISK(fc))
        if_state.has_path = FALSE;
#endif

#if ALIEN_BITS
    if (FC_ISAPPGEN(fc))
        if_state.has_path = FALSE;
#endif

    if (if_state.has_path)
    {
        if(STRLEN((FILECHAR *)if_state.fcCur.font_hdr) >= PATHNAMELEN)
            return ERRlong_font_name;

    /* jfd found that commenting out these two lines resolves a problem with
        Error 600 for CCC fonts (which appeared after the performance fix just
        below was integrated by jwd). */

        /*** STRCPY(if_state.pathname, (FILECHAR *)if_state.fcCur.font_hdr); ***/
        /*** if_state.fcCur.font_hdr = (LPUB8)if_state.pathname; ***/
    }
#endif  /* DISK_FONTS */

     /* Disable this code: it creates a TT performance issue, as comp_pix() 
         is called multiple times if CGIFfont() is called per character, even
        though the same fontcontext is used. (jwd, 07/15/03) */

     /* 
      * force FCis_equal() to fail so that
      * comp_pix() is called for first characters
      * of PostScript and TrueType fonts
      */

      /*** if_state.cur_loc_fc.font_hdr =  (LPUB8)0; ***/  /* 10-6-94 */

#if FCO_RDR     /* Save the UFST FCO handle in if_state.FCObject. 05-26-94, mby */
                /* The application handle is in the high 16 bits of fc->font_id */
    if (FC_ISFCO(fc))
    {
        MEM_HANDLE mh;
        
        UW16 status = fco_GetMemHandle(FSA (SL32)(fc->font_id >> 16), &mh);
DBG1("fc->font_id:%d\r\n",fc->font_id);
        if (status)
        {
            if_state.pserver->FCObject = 0;
            return status;
        }
        if_state.pserver->FCObject = mh;
    }
#endif  

#if ASIAN_ENCODING && TT_RDR
    if ( FC_ISTT(fc) && is_it_Asian(if_state.fcCur.ssnum) 
       && (if_state.symbolset.curssnum != if_state.fcCur.ssnum) )
    {
    if_state.symbolset.curssnum = if_state.fcCur.ssnum;
    }
#endif  /* ASIAN_ENCODING */

  /*  Read in new symbol if necessary and set up
   *  ss_first_code and ss_last_code.
   */
   /* For a PCLEO, if ssnum is not in our available list, fc->ssnum == 0 */
   /* an symbolset.current_ssnum reinitialized to 0 so SYMnew() should   */
   /* return success.                                        -ss 7/31/92 */

#if ALIEN_BITS
   /* For Application Generated Bitmaps, DO NOT call SYMnew or SYMnoMap */
    if (FC_ISAPPGEN(fc))      /* 06-14-94 */
        return SUCCESS;
#endif

    /*** review the rewritten logic again - sandra, 28 Jul 04 ***/
    if (fc->ssnum != DL_SYMSET && !useMapping 
#if PCLEO_RDR
          && (if_state.PCL_font_type != PCL_UNBOUND_FONT)
#endif
          )
    {
            if (!SYMnoMap(FSA if_state.fcCur.font_hdr, if_state.fcCur.format))
                return ERR_IXnew_ss;
    }

DBG1("fc->ssnum:%d\r\n",fc->ssnum);


    if (fc->ssnum != DL_SYMSET && FC_SSMAP(&if_state.fcCur))
    {
        if (!SYMnew(FSA if_state.fcCur.ssnum, if_state.fcCur.format))
            return ERR_IXnew_ss;
    }

    return status;

}       /* CGIFFfont() */
/*--------------------------------------------------------------------*/
/*  All entries below are conditionally compiled depending on which
 *  options have been set in cgconfig.h
 */


#if CHAR_HANDLE

/*-----------------------*/
/*    CGIFFchar_handle   */
/*-----------------------*/
/*  Return a handle  to the requested character IFBITMAP.  */
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFchar_handle (FSP UL32 chId, PHIFBITMAP phbm, SW16 alt_width)
#else
UW16 CGENTRY CGIFFchar_handle(chId, phbm, alt_width)
    UL32       chId;
    PHIFBITMAP phbm;
    SW16       alt_width;
#endif /* ANSI_DEFS */
{
    /* First, let's check if a DL bitmap is being processed. This check needs to be */
    /* at the character level, this flag is disabled when plugin processing occurs. */
    /* jwd, 07/21/03.                                                               */

#if PCLEO_RDR
    if (if_state.PCL_FSTTechnology == PCL_BITMAP_FONT)
       if_state.DLBmpInProcess = TRUE;
#endif
    
    /* rjl 9/25/2002 - At this time, only True Type can have a 32bit chId */

    if_state.alt_width = alt_width;
    return makechar(FSA (PFONTCONTEXT)&if_state.fcCur, chId, phbm);
}
#endif  /*  CHAR_HANDLE  */

/* -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- */


#if CACHE

/* do_bitmap() is called from CGIFchar() if banding is in effect and we are making bitmaps (rather than outlines) */
#if BANDING
#if defined (ANSI_DEFS)
UW16 MLOCAL do_banding(FSP UL32 chId, PPIFBITMAP ppbm, PHIFBITMAP hbm)
#else
UW16 MLOCAL do_banding(chId, ppbm, hbm)
    UL32 chId;
    PPIFBITMAP ppbm;
    PHIFBITMAP hbm;
#endif
{
    IFBITMAP bm;
    PIFBITMAP pbm;
    IFTILE   iftile;
    UW16      status;

#if SCALE_MATRIX   /* 3-25-98 jfd */
    /* UFST does not currently support banding using a
    scale matrix other than Typographer */
    if (if_state.fcCur.fc_type != FC_TYPO_TYPE)
        return ERRbanding_not_supported;

#if (SCALE_MATRIX & TYPO_SCALE_MATRIX)
    if ( !((if_state.fcCur.s.t.rotate.x == F_ONE && if_state.fcCur.s.t.rotate.y == 0)     /* 0 deg */
         ||(if_state.fcCur.s.t.rotate.x == -F_ONE && if_state.fcCur.s.t.rotate.y == 0)) ) /* 180 deg */
        return ERR_invalid_band;
#endif

#else
    if ( !((if_state.fcCur.rotate.x == F_ONE && if_state.fcCur.rotate.y == 0)     /* 0 deg */
         ||(if_state.fcCur.rotate.x == -F_ONE && if_state.fcCur.rotate.y == 0)) ) /* 180 deg */
        return ERR_invalid_band;
#endif    /* SCALE_MATRIX */

    MEMSET(&bm, 0, BMHEADERSIZE);
    status = CGIFFbmheader(FSA chId, &bm, 0);
    if (status && (status != ERR_fixed_space))
    {
        DBG1("CGIFbmheader() failed: %d\n", status);
        return status;
    }
    else if (!status && if_state.num_loops)
    {
        iftile.x = 0;
        iftile.width = bm.black_width;
        iftile.depth = if_state.fcCur.band_top;

#if !SCALE_MATRIX
        if (if_state.fcCur.rotate.x == F_ONE)  /* 0 deg rotation */
            iftile.y = (bm.black_depth - (SW16)(bm.yorigin >> 4L)) + if_state.fcCur.band_bot;
        else                          /* 180 deg rotation */
            iftile.y = ((bm.black_depth - (SW16)(bm.yorigin >> 4L)) - if_state.fcCur.band_bot)
                           - if_state.fcCur.band_top;
#endif
#if (SCALE_MATRIX & TYPO_SCALE_MATRIX)
        if (if_state.fcCur.s.t.rotate.x == F_ONE)  /* 0 deg rotation */
            iftile.y = (bm.black_depth - (SW16)(bm.yorigin >> 4L)) + if_state.fcCur.band_bot;
        else                          /* 180 deg rotation */
            iftile.y = ((bm.black_depth - (SW16)(bm.yorigin >> 4L)) - if_state.fcCur.band_bot)
                           - if_state.fcCur.band_top;
#endif

        status = CGIFFtile(FSA &iftile, &pbm);
        if (status)
        {
            DBG1("CGIFtile() failed: %d\n", status);

            /* If band is empty, just load escapement and em box info */

            if (status == ERR_invalid_tile) /* 09-02-97 jfd */
            {
                MEMSET((LPUB8)pbm, (SL32)0, (SL32)sizeof(IFBITMAP) );
                   pbm->escapement = if_state.cs.escapement;
                   pbm->du_emx     = if_state.cs.du_emx;
                   pbm->du_emy     = if_state.cs.du_emy;
                   *ppbm = pbm;
            }

            return status;
        }

        *hbm = if_state.htileBM; /* from CGIFtile() ???? */
        if_state.htileBM = NIL_MH;     /* Handle of last made tile part   */
        return status;    /* will be zero at this point */
    }
    /* this is the return path for (status == ERR_fixed_space) or (!status && !if_state.num_loops) */
    return status;

}    /* do_banding */
#endif  /* BANDING */


/*-----------------------*/
/*    CGIFFchar          */
/*-----------------------*/
/*  Character generation used with AGFA supplied character cache.
 *  May be used with internal or external memory manager.
 *  Return a pointer to the requested character IFBITMAP.
 *  Return nil if the character is not in the cache and cannot be
 *  made or if bad input data.
 *  If caller ID has changed since the last call to this function, then the 
 *  saved state (from CGIFconfig, CGIFfont) of the caller must be restored.
 */

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFchar (FSP UL32 chId, PPIFBITMAP ppbm, SW16 alt_width)
#else
UW16 CGENTRY
CGIFFchar(chId, ppbm, alt_width)
    UL32      chId;
    PPIFBITMAP ppbm;
    SW16       alt_width;
#endif /* ANSI_DEFS */
{
    HIFBITMAP  hbm;
    UW16      status;
#if USE_ASIAN_CACHE
    MEM_HANDLE hItem;
#else
    PHIFBITMAP phbm;
#endif /* USE_ASIAN_CACHE */


    /* First, let's check if a DL bitmap is being processed. This check needs to be */
    /* at the character level, this flag is disabled when plugin processing occurs. */
    /* jwd, 07/21/03.                                                               */

#if PCLEO_RDR
    if (if_state.PCL_FSTTechnology == PCL_BITMAP_FONT)
       if_state.DLBmpInProcess = TRUE;
#endif

    DBG1("CGIFchar(%lu)\n", chId);

    status = SUCCESS;  /* initialize in case bitmap is already cached */

    if (!if_state.pfontCur)
    {
      *ppbm = (PIFBITMAP)0;
      status = ERR_no_font;
      return status;
    }

  if (FC_NO_SSMAP(&if_state.fcCur))
  {
#if PCLEO_RDR
    if ( !((if_state.fontindex.font_type & FC_EXTERN_TYPE) == FC_EXTERN_TYPE) )
#endif  /* PCLEO_RDR */
       chId = *(UL32 *)if_state.chIdptr;    /* rjl 9/19/2002 - was (UW16)*/
  }


#if USE_ASIAN_CACHE
    /*
     * not found in cache case handled below (same as for 
     * non-Asian Encoding...
     */

    /* If processing a character from a bitmap font, the data will not be cached, */
    /* so let's limit the code to what we need to execute. jwd, 07/21/03.         */

if ( (hItem = CACbmLookup(FSA if_state.pfontCur, chId)) != NIL_MH )
    {
      *ppbm = (PIFBITMAP)MEMptr(hItem);
#else
    /*
     * 10/25/93 maib
     * if a handle to the bitmap is found, set the pointer and update
     * the LRU list. otherwise start the process of creating it...
     */
if ( *(phbm = if_state.pfontCur->hbuf + chId))
    {
      *ppbm = (PIFBITMAP)MEMptr(*phbm);
#endif /* USE_ASIAN_CACHE */

#if CACHE_BY_REF
      /* Increment "reference counter" if using "cache-by-reference" method */
     if ( ((PIFBITMAP)*ppbm)->ref_counter < MAX_ULONG)
        ((PIFBITMAP)*ppbm)->ref_counter++;    /* increment "cache-by-reference" counter */
     else
        return ERR_ref_counter_overflow;
#endif    /* CACHE_BY_REF */

      /*
       *  Make buffer most recently used if not already done
       */
      if (((PIFBITMAP)*ppbm)->notmru)
      {
        ((PIFBITMAP)*ppbm)->notmru = 0;  /* Keep from doing this again       */
#if USE_ASIAN_CACHE
        dll_remove(FSA hItem);            /* Remove from lru list             */
        remove_from_list(FSA hItem, if_state.pfontCur);
                                      /* Remove from IFBITMAP list        */
        dll_after(FSA if_state.pserver->hBMlru, hItem);     /* Link at the head of the lru list */
        insert_at_head_of_list(FSA hItem, if_state.pfontCur);
                                      /* Link at the head of IFBITMAP list*/
#else
        dll_remove(FSA *phbm);             /* Remove from lru list             */
        dll_after(FSA if_state.pserver->hBMlru, *phbm);      /* Link at the head of the lru list */
#endif /* USE_ASIAN_CACHE */
      }

       /* If this is a space character and it has already been cached,
        * "status" will not be set to ERR_fixed_space. Check if this
        * character is a fixed space and set status appropriately.
        *  10-08-93 jfd
        */
        if (FC_ISBITMAP(&if_state.fcCur)   /* 10-03-96 jfd */
#if GRAYSCALING
                   || FC_ISGRAY(&if_state.fcCur)   /* !! 11-06-96 mby */
#endif
                                       )
        {
          if (!(((PIFBITMAP)(*ppbm))->width) && !(((PIFBITMAP)(*ppbm))->depth))
            status = ERR_fixed_space;
        }
#if OUTLINE
        else                      /* 10-03-96 jfd */
        {                         /* 10-03-96 jfd */
          if (!(((PIFOUTLINE)*ppbm)->size))
            status = ERR_fixed_space;
        }                         /* 10-03-96 jfd */
#endif
#if COMPRESSED_CACHE
      /*  Decompress character into font specific buffer. */
        {
            UW16 status;
            if(if_state.pfontCur->hifbm == NIL_MH)
            {
                DBG("CGIFchar() doesn't have a valid pfontCur\n");
                status = ERRcmpr_data;   /* this can't happen */
                return status;
            }
            status = decompress_ifbitmap(FSA *ppbm, if_state.pfontCur->pifbm);
            if(status == ERRcmpr_notcompressed)
                status = SUCCESS;  /* wasn't compressed */
            else if (status)       /* error or space char */
                return status;
            else
                *ppbm = if_state.pfontCur->pifbm;
        }
#endif
    }
    else       /* not found in the cache */
    {
        if_state.alt_width = alt_width;

#if BANDING

    /* if banding is in effect, and we are returning bitmaps, 
        and UFST (rather than the application) is making bitmaps,
         then call new function do_banding()  */

        if ((if_state.fcCur.band_top || if_state.fcCur.band_bot) &&
            FC_ISBITMAP(&if_state.fcCur) && !FC_ISAPPGEN(&if_state.fcCur))
        {
            status = do_banding(FSA chId, ppbm, &hbm);

            /* band created successfully: set up to add this in CACinsert, below */
            if (!status && if_state.num_loops)
                goto insert;
            else if (status && (status != ERR_fixed_space))
                return status;

        /* fall through to regular case if (ERR_fixed_space or !if_state.num_loops) */

         }

#endif  /* BANDING */

        /* this is the regular (non-banding) case */

        status = makechar(FSA (PFONTCONTEXT)&if_state.fcCur, chId, (PHIFBITMAP)&hbm);

        /* If character is fixed space, cache it anyway to save
         * the metrics information
         */

        if (status && (status != ERR_fixed_space) && (status != ERRDLBmpInProcess))

        {
          DBG("    makechar() failed\n");
          return status;
        }
#if BANDING
insert:
#endif
#if PCLEO_RDR
        if (!if_state.DLBmpInProcess)
#endif
        {
            hbm = CACinsert(FSA hbm, chId);      /* Insert in cache  */
        }
        *ppbm = (PIFBITMAP)MEMptr(hbm);         /* but not for PCL  */


#if CACHE_BY_REF
        /* Initialize "reference counter" if using "cache-by-reference" method */
        ((PIFBITMAP)*ppbm)->ref_counter = 1;
#endif    /* CACHE_BY_REF */

    }                                           /* DL bitmaps.      */
                                                /* jwd, 07/21/03.   */

    return status;
}

#if CACHE_BY_REF
/* New "cache-by-reference" caching method */
/*----------------------*/
/*    CGIFFchar_by_ref   */
/*----------------------*/
/*  Character generation used with AGFA supplied character cache
 *  and "cache-by-reference" method.
 *  May be used with internal or external memory manager.
 *  Return pointers to the requested character IFBITMAP.
 *  Increments the cache-by-reference counter.
 *  Return nil if the character is not in the cache and cannot be
 *  made or if bad input data.
 *  If caller ID has changed since the last call to this function, then the 
 *  saved state (from CGIFconfig, CGIFfont) of the caller must be restored.
 */
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFchar_by_ref (FSP UL32 chId, PPIFBITMAP ppbm, SW16 alt_width)
#else
UW16 CGENTRY
CGIFFchar_by_ref(chId, ppbm, alt_width)
    UL32      chId;
    PPIFBITMAP ppbm;
    SW16       alt_width;
#endif /* ANSI_DEFS */
{
    UW16 status;

//Send_String("enter CGIFFchar_by_ref\r\n");

    DBG1("CGIFchar_by_ref(%lu)\n", chId);

    status = CGIFFchar(FSA chId, ppbm, alt_width);
    return status;
}

#endif    /* CACHE_BY_REF */

#endif  /* CACHE */

/* -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- */


#if CHAR_SIZE


/*-----------------------*/
/*    CGIFFchar_size     */
/*-----------------------*/
/* Character generator for application managed bitmap buffers */

#if defined (ANSI_DEFS)
#if (MAX_BM_BITS > 16)
UW16  CGENTRY CGIFFchar_size (FSP UL32 chId, LPSL32 size, SW16 alt_width)
#else
UW16  CGENTRY CGIFFchar_size (UL32 chId, LPUW16 size, SW16 alt_width)
#endif /* MAX_BM_BITS */
#else /* !ANSI_DEFS */
UW16  CGENTRY CGIFFchar_size (chId, size, alt_width)
    UL32    chId;
#if (MAX_BM_BITS > 16)
    LPSL32    size;
#else
    LPUW16   size;
#endif
    SW16     alt_width;
#endif /* ANSI_DEFS */
{
    UW16 status;
    SW16 idx;
    SL32  lsize[CHAR_SIZE_ARRAYSIZE];

    /* First, let's check if a DL bitmap is being processed. This check needs to be */
    /* at the character level, this flag is disabled when plugin processing occurs. */
    /* jwd, 07/21/03.                                                               */

#if PCLEO_RDR
    if (if_state.PCL_FSTTechnology == PCL_BITMAP_FONT)
       if_state.DLBmpInProcess = TRUE;
#endif

    /* rjl 9/30/2002 - At this time, only True Type can have a 32bit chId */
    DBG1("CGIFchar_size(%lu)\n", chId);

/* !SCALE_MATRIX test added because, otherwise, point_size and set_size
    fields of FONTCONTEXT are undefined (sandra, 24 Jan 2000) */
#if PSEUDO_HALF_WIDTH && !SCALE_MATRIX && ASIAN_ENCODING
   if ( is_it_Asian(if_state.fcCur.ssnum) )
      if ((chId >= 0x20) && (chId < 0xff ))
      {
         UW16 wbuf[2];
        status = CGIFFwidth(FSA chId, 1, 4, &wbuf[0]);
        alt_width = wbuf[0]>>1;
        /*if_state.fcCur.set_size = (SW16)(if_state.fcCur.set_size * 0.75);*/ 
          if_state.fcCur.point_size = (SW16)(if_state.fcCur.point_size * 0.75);
      }
      else
      {
          alt_width = 0;
          /*if_state.fcCur.set_size = (SW16)(if_state.fcCur.point_size);*/
            if_state.fcCur.point_size = (SW16)(if_state.fcCur.set_size);
       }
#endif /* PSEUDO_HALF_WIDTH && !SCALE_MATRIX && ASIAN_ENCODING */

#if GRAYSCALING
    if(FC_ISGRAY(&if_state.fcCur))
    {
        status = ERRchar_size_not_supported;
        return status;
    }
#endif

    if_state.alt_width = alt_width;        /* Alternate width */

    /*    First, let's initialize the values of lsize. If the application is */
    /* not processing a compound character,  or does not have NZW turned on, */
    /* this step will avoid garbage being placed in those size fields.       */
    

    for (idx=0; idx < CHAR_SIZE_ARRAYSIZE; idx++)
        lsize[idx] = 0;

    /* Also reset num_loops and nloop (used to determine whether we have
        a space character). */
    /* This change is by customer request - in the standard path, these fields
        are cleared at the start of MAKifbmheader(), which is called from 
        MAKfontSize(), below. */
        
    if_state.num_loops = 0;
    if_state.cs.nloop = 0;

    status = MAKfontSize(FSA &if_state.fcCur, chId, lsize);

    for (idx=0; idx < CHAR_SIZE_ARRAYSIZE; idx++)
    {
#if (MAX_BM_BITS > 16)
        size[idx] = lsize[idx];
#else
        size[idx] = (UW16)lsize[idx];
#endif
    }

    return status;
}
#endif  /* CHAR_SIZE */

/* -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- */


#if (TILE && CGBITMAP)
/*-----------------------*/
/*    CGIFFbmheader      */
/*-----------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFbmheader (FSP UL32 chId, PIFBITMAP pbm, SW16 alt_width)
#else
UW16 CGENTRY CGIFFbmheader (chId, pbm, alt_width)
    UL32     chId;
    PIFBITMAP pbm;
    SW16      alt_width;
#endif /* ANSI_DEFS */
{
    UW16 status = 0;

    if_state.alt_width = alt_width;        /* Alternate width */

#if STIK && (TT_DISK || TT_ROM || TT_ROM_ACT)
    if_state.update_reflines_flag_set = FALSE;

redo:
#endif

#if LINKED_FONT
    if  ( FC_ISLINKEDFONT(&if_state.fcCur) )
        status = LFNT_MAKifbmheader(FSA &if_state.fcCur, chId, pbm);
    else

#endif

    status = MAKifbmheader(FSA &if_state.fcCur, chId, pbm);

#if STIK && (TT_DISK || TT_ROM || TT_ROM_ACT)    /* 09-23-02 jfd */
    if (FC_ISTT(&if_state.fcCur) && status == ERR_reflines_needed)
    {
    if_state.update_reflines_flag_set = TRUE;
        extract_reflines(FSA &if_state.fcCur);
        goto redo;
    }
#endif
    return status;
}


#if CHAR_HANDLE
/*-----------------------*/
/*    CGIFFtile_handle   */
/*-----------------------*/

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFtile_handle (FSP PIFTILE piftile, PHIFBITMAP phbm)
#else
UW16 CGENTRY CGIFFtile_handle (piftile, phbm)
    PIFTILE piftile;
    PHIFBITMAP phbm;
#endif /* ANSI_DEFS */
{
  UW16 status;

    status = bitmap_tile(FSA piftile, phbm);
    return status;
}
#endif /* CHAR_HANDLE */

#if CACHE
/*-----------------------*/
/*    CGIFFtile          */
/*-----------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFtile (FSP PIFTILE piftile, PPIFBITMAP ppbm)
#else
UW16 CGENTRY CGIFFtile (piftile, ppbm)
    PIFTILE piftile;
    PPIFBITMAP ppbm;
#endif /* ANSI_DEFS */
{
    UW16     status;

    status = bitmap_tile(FSA piftile, &if_state.htileBM);
#if BANDING  /* 09-02-97 jfd */
    if ( (if_state.fcCur.band_top || if_state.fcCur.band_bot) &&
          status == ERR_invalid_tile)
    {
       *ppbm = (PIFBITMAP)MEMptr(if_state.htileBM);
       return status;
    }
    else
#endif
    if (status)
        return status;

    *ppbm = (PIFBITMAP)MEMptr(if_state.htileBM);
    return SUCCESS;
}

#endif /* CACHE */
#endif  /* TILE && CGBITMAP */

#if WIDTHS
/*-----------------------*/
/*    CGIFFwidth         */
/*-----------------------*/

#if defined (ANSI_DEFS)
#if WIDTH_NOSYMMAP
UW16 CGENTRY CGIFFwidth (FSP PWIDTH_LIST_INPUT_ENTRY PointerToList, UW16 NumEntriesInList,
                        UW16 buffer_size, LPUW16 buffer)
#else
UW16 CGENTRY CGIFFwidth (FSP UL32 first_chId, UW16 num_chId,
                        UW16 buffer_size, LPUW16 buffer)
#endif    /* WIDTH_NOSYMMAP */
#else
#if WIDTH_NOSYMMAP
UW16 CGENTRY CGIFFwidth (PointerToList, NumEntriesInList, buffer_size, buffer)
   PWIDTH_LIST_INPUT_ENTRY PointerToList;
   UW16   NumEntriesInList;
   UW16   buffer_size;
   LPUW16 buffer;
#else
UW16 CGENTRY CGIFFwidth (first_chId, num_chId, buffer_size, buffer)
    UL32  first_chId;
    UW16  num_chId;
    UW16  buffer_size;
    LPUW16 buffer;
#endif /* WIDTH_NOSYMMAP */
#endif /* ANSI_DEFS */
{

    UW16    status = ERR_bad_chID;    /* for (num_chId == 0) case */
    /* This initialization is by customer request - in the standard path, 
       the status is initialized by the call to IXget_fnt_index(), below. */ 


    LPUW16   p;
    UW16    chId;

#if WIDTH_NOSYMMAP
    PWIDTH_LIST_INPUT_ENTRY CharData = (PWIDTH_LIST_INPUT_ENTRY )PointerToList;
    UW16      loop;
    VOID   *psName = NULL;
#else
    SL32    q;
#endif

#if WIDTH_NOSYMMAP
    DBG4("CGIFwidth(%lu, %u, %u, %lu)\n",
                    PointerToList, NumEntriesInList, buffer_size, buffer);
#else
    DBG4("CGIFwidth(%lu, %u, %u, %lu)\n",
                    first_chId, num_chId, buffer_size, buffer);
#endif

    status = IXget_fnt_index(FSA &if_state.fcCur);
    if (status)
        goto WIDTH_EXIT;

#if WIDTH_NOSYMMAP
   if(buffer_size < 4 * NumEntriesInList)
#else
    if(buffer_size < 4*num_chId)  /* buffer must now hold em box size too */
#endif
    {
      DBG("    buffer too small\n");
      status = ERR_buffer_too_small;
      goto WIDTH_EXIT;
    }

    p = (LPUW16)buffer;
#if !WIDTH_NOSYMMAP
#if ((IF_RDR || PST1_RDR) && (TT_RDR || FCO_RDR))
    if (FC_ISTT(&if_state.fcCur) || FC_ISFCO(&if_state.fcCur))
        q = SYMBOLSET_TT;
    else
        q = SYMBOLSET_IF;
#endif
#if !(TT_RDR || FCO_RDR)
    q = SYMBOLSET_IF;
#endif
#if !(IF_RDR || PST1_RDR)
    q = SYMBOLSET_TT;
#endif

/* In CFF, a character 'environment' must be set up before attempting widths   */
/* This needs to be rethought. Is there another way to do this? jwd, 10/15/02 */

#if CFF_RDR
#if CACHE
   status = CGIFFchar(FSA (UW16)first_chId, (PPIFBITMAP)&buffer, 0);

#elif CHAR_SIZE
#if (MAX_BM_BITS > 16)
   status = CGIFFchar_size (FSA (UW16)first_chId, (LPSL32)&buffer, (SW16)0);
#else
   status = CGIFFchar_size (FSA (UW16)first_chId, (LPUW16)&buffer, (SW16)0);
#endif /* MAX_BM_BITS */

#else /* CHAR_HANDLE */
{
   HIFBITMAP hbm = NIL_MH;
   status = CGIFFchar_handle(FSA (UW16)first_chId, &hbm, 0);

   if (hbm)
   {
#if IFBITSPLIT
       PIFBITMAP pbm = (PIFBITMAP)MEMptr(hbm);
       CHARfree(FSA pbm->datahandle);    /* free the actual bits (special case) */
#endif
       CHARfree(FSA hbm);
   }
}
#endif    /* CACHE / CHAR_SIZE / CHAR_HANDLE */
#endif /* CFF_RDR */
#endif   /* !WIDTH_NOSYMMAP, jwd, 10/15/02. */

#if WIDTH_NOSYMMAP
    for (loop = 0; loop < NumEntriesInList; loop++)
    {
        /* Code selection based on fcCur format selection. */
        if (FC_ISTT(&if_state.fcCur))
        {
            chId = CharData->CharType.TT_unicode;
            psName = NULL;
        }
        else if (FC_ISIF(&if_state.fcCur))
        {
            chId = CharData->CharType.IF_cgnum;
            psName = NULL;
        }
          else if (FC_ISFCO(&if_state.fcCur))
        {
            chId = CharData->CharType.MT_unicode;
            psName = NULL;
        }
          else if (FC_ISPST1(&if_state.fcCur))
        {
            chId = 0;
             psName = CharData->CharType.PS_name;
           }

          status = CGIFchIdptr(FSA &chId, psName);
          if (status)
        {
            *p++ = ERR_char_unavailable;  /* 0x7FFF, 05-24-95 */
             *p++ = 0;                     /* em box size      */
             continue;
        }
          else
        {
            *p++ = chwidth(FSA chId);
             *p++ = if_state.cs.du_emx;    /* em box size */
        }
 
          CharData++;
    }    /* end for (WIDTH_NOSYMMAP case) */

#else
/* Original line: for(chId=first_chId; chId<first_chId + num_chId; chId++)*/
/* Modify the above line to be following to avoid a potential bug         */
/* when chId is 0xffff and num_chId is 1. The addition 0xffff + 1         */
/* may cause an endless loop.                               6-26-97   jqz */                
    for (chId = first_chId; num_chId > 0 ; num_chId --, chId ++ )
    {
        if (
#if ASIAN_ENCODING
            !is_it_Asian(if_state.fcCur.ssnum) &&
#endif
                (chId < if_state.symbolset.ss_first_code[q]  ||
                    if_state.symbolset.ss_last_code[q] < chId)   )
        {
            *p++ = ERR_char_unavailable;  /* 0x7FFF, 05-24-95 */
            *p++ = 0;  /* em box size */
        }
        else
        {         
            *p++ = chwidth(FSA chId);
            *p++ = if_state.cs.du_emx;  /* em box size */
        }

    }    /* end for (SYMSET_MAPPING case) */
#endif
    status = SUCCESS;

WIDTH_EXIT:
    return status;
}
#endif  /* WIDTHS */


#if IF_RDR
#if SEGACCESS
/*-------------------*/
/*   CGIFFsegments   */
/*-------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFsegments (FSP SL32 tfnum, UW16 key, LPUW16 psize, LPSB8 pbuffer)
#else
UW16 CGENTRY CGIFFsegments (tfnum, key, psize, pbuffer)
    SL32        tfnum;
    UW16       key;
    LPUW16      psize;
    LPSB8       pbuffer;
#endif /* ANSI_DEFS */
{
    UW16       status;
    PBUCKET     b;
    UW16       m;
    UW16       c;
    UW16       i;
    LPSB8       p;

  /*  Load typeface  */

#if (DYNAMIC_FONTS && (SEGACCESS == 2))  /* 4-20-94 jfd */
   if_state.fcCur.font_id = 0;
   if_state.fcCur.font_hdr = (LPUB8)tfnum;
   if_state.fcCur.format = 0;
#endif
  
    /* UsePlugins member of the new Bucket was not initialized properly
       when CGIFsegments() was called before CGIFfont().  ks - Aug. 20/99 */

    if_state.usePlugins = TRUE;

  if (FC_NO_SSMAP(&if_state.fcCur) && FC_ISEXTERN(&if_state.fcCur))
        if_state.usePlugins = FALSE;

    status = IXget_fnt_index(FSA &if_state.fcCur);
    if(status)
    {
        DBG1("IXget_fnt_index() failed: status %d\n", status);
        return status;
    }
    status = BUCKfind(FSA TF_SENSITIVE, CREATE_BUCKET, &b);
    if(status)
    {
        DBG1("BUCKfind() failed: status %d\n", status);
        return status;
    }

  /* Get segment memory handle and size */

    switch (key)
    {
        case FACE_GLOBAL_KEY:              /* Entire face global segment */
                m = 0;
                c = b->p.in.sfgseg;
                break;
        case GIF_KEY:                      /* Global Intellifont segment */
                m = b->p.in.ogif;
                c = b->p.in.gifct;
                break;
        case TRACK_KERN_KEY:
                m = b->p.in.otrack_kern_seg;
                c = b->p.in.strack_kern_seg;
                break;
        case TEXT_KERN_KEY:
                m = b->p.in.otext_kern_seg;
                c = b->p.in.stext_kern_seg;
                break;
        case DESIGN_KERN_KEY:
                m = b->p.in.odesign_kern_seg;
                c = b->p.in.sdesign_kern_seg;
                break;
        case WIDTH_KEY:                    /* character width segment    */
                m = b->p.in.owidth_seg;
                c = b->p.in.swidth_seg;
                break;
        case ATTRIBUTE_KEY:                /* Attribute header           */
                m = b->p.in.oattribute;
                c = b->p.in.sattribute;
                break;
        case RASTER_KEY:                   /* Raster parameter           */
                m = b->p.in.orast;
                c = b->p.in.srast;
                break;
        case TF_HEADER_KEY:                /* Typeface Header segment    */
                m = b->p.in.otf_header_seg;
                c = b->p.in.stf_header_seg;
                break;
        case COMPOUND_KEY:                 /* Compound character         */
                m = b->p.in.ocompound_seg;
                c = b->p.in.scompound_seg;
                break;
        case DISPLAY_KEY:                  /* Display header             */
                m = b->p.in.odisplay;
                c = b->p.in.sdisplay;
                break;
        case FONT_ALIAS_KEY:               /* Font Alias segment         */
                m = b->p.in.ofont_alias_seg;
                c = b->p.in.sfont_alias_seg;
                break;
        case COPYRIGHT_KEY:                /* Copyright notice           */
                m = b->p.in.ocopy;
                c = b->p.in.scopy;
                break;
        default:
                return ERRinvalid_seg_key;
                break;
    }

  /* Return required buffer size or copy the data to caller's buffer */

    if(!pbuffer)
        *psize = c;
    else
    {
        if(c)
        {
            p = fgseg(FSA b) + m;
            for(i=0; i<c; i++)
                *pbuffer++ = *p++;
        }
    }

    return SUCCESS;
}

#endif  /* SEGACCESS */
#endif  /* IF_RDR */

/*------------------*/
/*  CGIFFfont_purge  */
/*-----------------------------*/
/*  CGIFFcache_purge (obsolete) */
/*-----------------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfont_purge (FSP PFONTCONTEXT fc)
#else
UW16 CGENTRY CGIFFfont_purge (fc)
   PFONTCONTEXT fc;
#endif /* ANSI_DEFS */
{
    UW16 status;
    PBUCKET p_bucket;

    DBG("CGIFfont_purge\n");

#if CACHE
    status = CACpurge(FSA fc);
    if (status)
    {
      return status;
    }
#endif /* CACHE */

    status = IXget_fnt_index(FSA fc);
    if (status)
    {
      return status;
    }
    status = BUCKfind(FSA TF_SENSITIVE, PURGE_BUCKET, &p_bucket);

   /*    7/15/93 - rs
      Make sure the if_state copy of the fontcontext is also gone!
      Our own local copy is guaranteed to be reset the next time
      CGIFfont() is called - and it better be called before asking
      for any more characters.
   */
    MEMSET (&if_state.fcCur, '\0', sizeof (FONTCONTEXT));
    MEMSET (&if_state.cur_loc_fc, '\0', sizeof (FONTCONTEXT));
    /* Reset system copy of fontcontext too. */
    MEMSET (&if_state.pserver->cur_loc_fc, '\0', sizeof (FONTCONTEXT));

    return status;
}
/*--------------------*/
/*  CGIFFmem_purge  */
/*--------------------*/

#if defined (ANSI_DEFS)
UL32 CGENTRY CGIFFmem_purge (FSP UL32 ActionFlag)
#else
UL32 CGENTRY CGIFFmem_purge (ActionFlag)
   UL32 ActionFlag;
#endif /* ANSI_DEFS */
{
#if UFST_MULTITHREAD
    PBUCKET b;
    HBUCKET hb;
    HBUCKET next_hb;
#endif

    SL32 ActualMemoryFreed = 0;
    SL32 InitialCACHEMemory;
    SL32 InitialBUFFERMemory;

    DBG("CGIFFmem_purge\n");
    InitialCACHEMemory = if_state.pserver->mem_avail[CACHE_POOL];
    InitialBUFFERMemory = if_state.pserver->mem_avail[BUFFER_POOL];
#if UFST_MULTITHREAD
         if (if_state.pserver->client_count > 1) return ActualMemoryFreed;    /* 10-25-04 jfd - was 0 */
#endif    
    switch (ActionFlag)
      {
         
#if CACHE
    case CACHEPURGE:
         {
#if UFST_MULTITHREAD
        PFONT f;
        HIFFONT hf;
        HIFFONT next_hf;

        hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b;
        while(hf != if_state.pserver->hFNTlru)
        {
            f = (PFONT)MEMptr(hf);
            next_hf = f->link.b;
            CACfont_free(FSA hf);
            hf = next_hf;
        }
#else
         while(!dll_empty(FSA if_state.pserver->hFNTlru))
            CACfont_free(FSA ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b);
#endif
         ActualMemoryFreed = if_state.pserver->mem_avail[CACHE_POOL] - InitialCACHEMemory;
         break;
         }
#endif

      case BUFFERPURGE:
         {
#if UFST_MULTITHREAD
            hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f;   /* first BUCKET in lru list */
            while(hb != if_state.pserver->hBUCKlru)
            {
                b = (PBUCKET)MEMptr(hb);
                next_hb = b->link.f;
                BUCKfree(FSA hb);
                hb = next_hb;            /* next BUCKET in the list */
            }
#else
         while(!dll_empty(FSA if_state.pserver->hBUCKlru))
            BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
#endif
         ActualMemoryFreed = if_state.pserver->mem_avail[BUFFER_POOL] - InitialBUFFERMemory;
         break;
         }

      case CACHEBUFFERPURGE:
         {

         /* Delete both cache and buffer */
#if CACHE
#if UFST_MULTITHREAD
        PFONT f;
        HIFFONT hf;
        HIFFONT next_hf;

        hf = ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b;
        while(hf != if_state.pserver->hFNTlru)
        {
            f = (PFONT)MEMptr(hf);
            next_hf = f->link.b;
            CACfont_free(FSA hf);
            hf = next_hf;
        }
#else
         while(!dll_empty(FSA if_state.pserver->hFNTlru))
            CACfont_free(FSA ((PDLL)MEMptr(if_state.pserver->hFNTlru))->b);
#endif
         ActualMemoryFreed = if_state.pserver->mem_avail[CACHE_POOL] - InitialCACHEMemory;
#endif
#if UFST_MULTITHREAD
            hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b;
            while(hb != if_state.pserver->hBUCKlru)
            {
                b = (PBUCKET)MEMptr(hb);
                next_hb = b->link.b;
                BUCKfree(FSA hb);
                hb = next_hb;
            }
#else
         while(!dll_empty(FSA if_state.pserver->hBUCKlru))
            BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
#endif
         ActualMemoryFreed += if_state.pserver->mem_avail[BUFFER_POOL] - InitialBUFFERMemory ;
         break;
         }
        default:
         {
         ActualMemoryFreed = 0;
         break;
         }
      }

   return ActualMemoryFreed;
 }
/*---------------------*/
/*  CGIFFbucket_purge  */
/*---------------------*/

#if defined (ANSI_DEFS)
UL32 CGENTRY CGIFFbucket_purge (FSP UL32 ActionFlag)
#else
UL32 CGENTRY CGIFFbucket_purge (ActionFlag)
   UL32 ActionFlag;
#endif /* ANSI_DEFS */
   {
   SL32 ActualMemoryFreed = 0;
   SL32 InitialMemoryState, FinalMemoryState;

   DBG("CGIFbucket_purge\n");

   InitialMemoryState = if_state.pserver->mem_avail[BUFFER_POOL];

   switch (ActionFlag)
      {
      case DELETEALL:
         {
#if UFST_MULTITHREAD
            PBUCKET b;
            HBUCKET next_hb;
            HBUCKET hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f;   /* first BUCKET in lru list */

            while(hb != if_state.pserver->hBUCKlru)
            {
                b = (PBUCKET)MEMptr(hb);
                next_hb = b->link.f;
                BUCKfree(FSA hb);
                hb = next_hb;            /* next BUCKET in the list */
            }
#else
         while(!dll_empty(FSA if_state.pserver->hBUCKlru))
            BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
#endif

         break;
         }

      case DELETEALLBUTLOCKED:
         {
         HBUCKET hb;
#if UFST_MULTITHREAD
         PBUCKET b;
         HBUCKET next_hb;
#endif

         /* Let's prime the pump, with lru bucket */
         /* pointer to backwards pointer in list. */
         /* Not empty list, that is.              */

         if (!dll_empty(FSA if_state.pserver->hBUCKlru))
            {
           hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b;
#if UFST_MULTITHREAD
            while (hb != if_state.pserver->hBUCKlru)
            {
                b = (PBUCKET)MEMptr(hb);
                next_hb = b->link.b;

                /* More than one BUCKET could be locked */
                if (!(((PBUCKET)MEMptr(hb))->locked))
                    BUCKfree(FSA hb);  /* free BUCKET */
                hb = next_hb;            /* next BUCKET in the list */
            }
#else
            while (!(((PBUCKET)MEMptr(hb))->locked))
               {
               /* Only the MRU BUCKET will be locked */
               BUCKfree(FSA hb);  /* free lru BUCKET */

               hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b;
               }
#endif
            }

         break;
         }

      default:
         {
         UL32 upperThreshold = 0;
#if UFST_MULTITHREAD
            PBUCKET b;
            HBUCKET next_hb;
            HBUCKET hb;
#endif

         /* Approximate memory amount to free, if */
         /* available.  Validate input amount vs. */
         /* mem_fund, and then clean up. If value */
         /* plus mem_avail greater than mem_fund, */
         /* delete all buckets.                   */

         if (((SL32 )ActionFlag + if_state.pserver->mem_avail[BUFFER_POOL]) > if_state.pserver->mem_fund[BUFFER_POOL])
            {
            /**************************************/
            /* Unable to reach initial mem due to */
            /* housekeeping memory not related to */
            /* buckets,  but use for a upperbound */
            /* count anyway and check for a empty */
            /* list.                              */
            /**************************************/

            upperThreshold = (SL32 )if_state.pserver->mem_fund[BUFFER_POOL];
            }
         else
            upperThreshold = (SL32 )ActionFlag + if_state.pserver->mem_avail[BUFFER_POOL];

#if UFST_MULTITHREAD
            hb = ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->f;   /* first BUCKET in lru list */
            while ((if_state.pserver->mem_avail[BUFFER_POOL] < (SL32 )upperThreshold)
                && !dll_empty(FSA if_state.pserver->hBUCKlru)
                && hb != if_state.pserver->hBUCKlru)
            {
                b = (PBUCKET)MEMptr(hb);
                next_hb = b->link.f;
                BUCKfree(FSA hb);
                hb = next_hb;            /* next BUCKET in the list */
            }
#else
         while ((if_state.pserver->mem_avail[BUFFER_POOL] < (SL32 )upperThreshold)  && !dll_empty(FSA if_state.pserver->hBUCKlru))
            BUCKfree(FSA ((PDLL)MEMptr(if_state.pserver->hBUCKlru))->b);
#endif

         break;
         }
      }

   FinalMemoryState  = if_state.pserver->mem_avail[BUFFER_POOL];
   ActualMemoryFreed = FinalMemoryState - InitialMemoryState;

   return (UL32 )ActualMemoryFreed;
   }

/*---------------------------*/
/*  CGIFFhdr_font_purge      */
/*---------------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFhdr_font_purge (FSP PFONTCONTEXT fc)
#else
UW16 CGENTRY CGIFFhdr_font_purge (fc)
   PFONTCONTEXT fc;
#endif /* ANSI_DEFS */
{
    UW16 status;
    PBUCKET p_bucket;

#if CACHE
    status = CAChdr_purge(FSA fc);
    if (status)
    {
      return status;
    }
#endif /* CACHE */

    status = IXget_fnt_index(FSA fc);
    if (status)
    {
      return status;
    }
    status = BUCKfind(FSA TF_SENSITIVE, PURGE_BUCKET, &p_bucket);

   /*    7/15/93 - rs
      Make sure the if_state copy of the fontcontext is also gone!
      Our own local copy is guaranteed to be reset the next time
      CGIFfont() is called - and it better be called before asking
      for any more characters.
   */
    MEMSET (&if_state.fcCur, '\0', sizeof (FONTCONTEXT));
    MEMSET (&if_state.cur_loc_fc, '\0', sizeof (FONTCONTEXT));
    /* Reset system copy of fontcontext too. */
    MEMSET (&if_state.pserver->cur_loc_fc, '\0', sizeof (FONTCONTEXT));

    return status;
}


#if ROM
/*-------------------*/
/*  CGIFinitRomInfo  */
/*-------------------*/
/*  Use this routine to get the addresses of the IF.FNT and Uxx.SS into */
/*  ufst in a ROM based system.                                      */
#if defined (ANSI_DEFS)
GLOBAL SW16 CGIFinitRomInfo (FSP LPUB8 fblock_ptr, LPUB8 ss_ptr[])
#else
GLOBAL SW16 CGIFinitRomInfo ( fblock_ptr, ss_ptr )
  LPUB8 fblock_ptr;
  LPUB8 ss_ptr[];
#endif /* ANSI_DEFS */
{
    SL32 ii;

#if IF_ROM   
    if_state.fontindex.pfnt_index    = fblock_ptr;
#endif

DBG1("^^^^^^^^^^^^^^NSS_FILES:%d\r\n",NSS_FILES);

    for (ii=0; ii<NSS_FILES; ii++)
        if_state.symbolset.pss_directory[ii] = ss_ptr[ii];

    return SUCCESS;
}

#endif  /* ROM */


#if FCO_RDR
/*-----------------*/
/*  CGIFFfco_Open  */
/*-----------------*/
/*  This function reads a new Font Collection Object.
 *  fcName is the pointer to an FCO in ROM, or its pathname.
 *  FChandle is returned to the application.
 *  If status = error, then FChandle = is 0xFFFF
 *  If status = success, then FChandle = is between 0 and 0x7FFF;
 */

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfco_Open( FSP LPUB8 fcName, LPSW16 FChandle )
#else
UW16 CGENTRY CGIFFfco_Open( fcName, FChandle )
    LPUB8 fcName;
    LPSW16 FChandle;
#endif /* ANSI_DEFS */
{
    SL32  fcoHandle;
    UW16 status;
//  DBG("CGIFfco_Open()\n");

    status = fco_InitFCO( FSA &fcoHandle, fcName );
    
    
    if (status == SUCCESS)
        *FChandle = (SW16)fcoHandle;
    else
        *FChandle = (SW16) 0xFFFF;

    return status;
}


/*------------------*/
/*  CGIFFfco_Close  */
/*------------------*/
/*  This function closes a Font Collection Object whose handle is FChandle.
 */

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfco_Close( FSP SW16 FChandle )
#else
UW16 CGENTRY CGIFFfco_Close( FChandle )
    SW16 FChandle;
#endif /* ANSI_DEFS */
{
    UW16 status;

    DBG("CGIFfco_Close()\n");

    status = fco_DeleteFCO(FSA (SL32)FChandle);

    return status;
}


/*------------------*/
/*  CGIFFfco_Plugin  */
/*------------------*/
/*  This function permanently selects an FCO where the plugins are located.
 *  The handle of the FCO is 'FChandle'.
 */

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfco_Plugin( FSP SW16 FChandle )
#else
UW16 CGENTRY CGIFFfco_Plugin( FChandle )
    SW16 FChandle;
#endif /* ANSI_DEFS */
{
    UW16 status;

    DBG("CGIFfco_Plugin()\n");

#if PLUGINS
    status = fco_saveHndl(FSA (SL32)FChandle);
#else
    status = SUCCESS;
#endif

    return status;
}

#endif  /* FCO_RDR */

#if FNT_METRICS

/* ---------------------------- CGIFFfont_metrics ----------------------------
 *
 * Description: CGIFFfont_metrics() returns a font metrics object based on
 *                the current fontcontext.
 * Parameters:  mtx is a FONT_METRICS object.
 *
 * Notes: Requires FNT_METRICS==1 in cgconfig.h
 *        Not implemented for PST1 or IF.
 */
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFfont_metrics( FSP FONT_METRICS* mtx )
#else
UW16 CGENTRY CGIFFfont_metrics( mtx )
    FONT_METRICS* mtx;
#endif /* ANSI_DEFS */
{
    UW16 status;
    PBUCKET pBucket;

    DBG("CGIFfont_metrics\n");

    MEMSET(mtx, 0, sizeof(FONT_METRICS));

    if ((status = IXget_fnt_index(FSA &if_state.fcCur)) != SUCCESS)
        goto MTX_EXIT;
    if ((status = BUCKfind(FSA TF_SENSITIVE, CREATE_BUCKET, &pBucket)) != SUCCESS)
        goto MTX_EXIT;

    switch (if_state.fcCur.format & FC_FONTTYPE_MASK)
    {
#if FCO_RDR
        case FC_FCO_TYPE:
            status = fco_get_FontMetrics(FSA pBucket, mtx, TF_SENSITIVE);  /* for TFS and plugins */
            if (status)
                goto MTX_EXIT;
            break;
#endif

#if TT_RDR
        case FC_TT_TYPE:
            status = tt_get_FontMetrics(FSA pBucket, mtx, TF_SENSITIVE);  /* TFS only */
            if (status)
                goto MTX_EXIT;
            /* Now, do the plugins */
#if TT_TTPLUG
#define TTFPLUG_BUCKET_NR  1  /* always 1; plugin.ttf */
            if ((status = BUCKfind(FSA TTFPLUG_BUCKET_NR, CREATE_BUCKET, &pBucket)) != SUCCESS)
                goto MTX_EXIT;
#if FCO_RDR   /* => TT font uses plugins in MicroType format */
            status = fco_get_FontMetrics(FSA pBucket, mtx, TTFPLUG_BUCKET_NR);
#else
            status = tt_get_FontMetrics(FSA pBucket, mtx, TTFPLUG_BUCKET_NR);
#endif
#endif  /* TT_TTPLUG */
            if (status)
                goto MTX_EXIT;
            break;
#endif  /* TT_RDR */


#if PST1_RDR
        case FC_PST1_TYPE:   /* Not yet implemented */
#endif
 
#if IF_RDR
        case FC_IF_TYPE:   /* Not implemented */
#endif

        default:
            status = ERR_font_metrics;
            goto MTX_EXIT;
    }

    return SUCCESS;

MTX_EXIT:
    return status;

} /*** CGIFFfont_metrics ***/
#endif  /* FNT_METRICS */

/*****************************************************************/
/****                                                         ****/

#if FONTBBOX
/* BBoxRes is defined in "ix.h" */

#if IF_RDR
#if CGFIXED_PITCH
  /* union of slim plugins + f.p. plugins, normalized */
CONST BBoxRes IFplugin = { { -1251, -2700, 9631, 8331 }, 8782 };
#else
  /* union of slim plugins, normalized */
CONST BBoxRes IFplugin = { { -1251, -2196, 9631, 8331 }, 8782 };
#endif  /* CGFIXED_PITCH */
#if (PS_IFPLUG)
#if CGFIXED_PITCH
  /* union of 8 core fonts, slim plugins, & f.p. plugins, normalized */
CONST BBoxRes IFCOREplugin = { { -2189, -2700, 10499, 8391 }, 8782 };
#else
  /* union of 8 core fonts & slim plugins, normalized */
CONST BBoxRes IFCOREplugin = { { -2189, -2196, 10499, 8391 }, 8782 };
#endif  /* CGFIXED_PITCH */
#endif  /* PS_IFPLUG */
#endif  /* IF_RDR */

#if (TT_RDR && (TT_TTPLUG) && !FCO_RDR)
  /* TT Universal plugins */
CONST BBoxRes TTplugin = { { -23, -628, 1968, 1864 }, 2048 };
#endif

/* This is getting ridiculous. Set up the BBoxRes structs at init time?
 * For example, the data could be pulled from if.fnt. Anyway, it's not
 * the best idea to have the plugin bboxes as constants. mby 10/1/93
 */

#ifdef LINT_ARGS
MLOCAL VOID    bbox_union( BBoxRes*, BBoxRes* );
#if IF_PCLEOI
MLOCAL VOID    bbox_union_1( SW16, SW16, SW16, SW16, LPSW16, LPSW16, LPSW16, LPSW16 );
#endif

#else
MLOCAL VOID    bbox_union();
#if IF_PCLEOI
MLOCAL VOID    bbox_union_1();
#endif
#endif

#if IF_RDR
#define IF_FLUFF  1
#else
#define IF_FLUFF  0
#endif
#if TT_RDR
#define TT_FLUFF  1
#else
#define TT_FLUFF  0
#endif
#if PST1_RDR
#define PS_FLUFF  1
#else
#define PS_FLUFF  0
#endif
#if FCO_RDR
#define FCO_FLUFF  5
#else
#define FCO_FLUFF  0
#endif

/*-------------------*/
/*  CGIFFbound_box   */
/*-------------------*/
/*  This function returns an upper bound estimate of the font bounding box
 *  in output pixels. The estimate is not 100% guaranteed.
 */

#if defined (ANSI_DEFS)
#if VLCOUTPUT
UW16 CGENTRY CGIFFbound_box( FSP SL32 FontBBox[4], LPSW16 pVLCpower )
#else
UW16 CGENTRY CGIFFbound_box( FSP SL32 FontBBox[4] )
#endif /* VLCOUTPUT */
#else /* !ANSI_DEFS */
#if VLCOUTPUT
UW16 CGENTRY CGIFFbound_box( FontBBox, pVLCpower )
    SL32         *FontBBox;
    LPSW16        pVLCpower;
#else
UW16 CGENTRY CGIFFbound_box( FontBBox )
    SL32         *FontBBox;
#endif /* VLCOUTPUT */
#endif /* ANSI_DEFS */
{
FPNUM   bboxDU_fp[4];
SW16VECTOR  bboxpt[4];          /* the 4 corners transformed (ll, ul, ur, lr) */
FPNUM   fScale;                 /* scale factor applied to matrix[] */
SL32     fluffFactor, fluffFactorY;
FPNUM   matrix[4];              /* matrix trsnsform from design to output */
PBUCKET pBucket;                /* of TFS font */
UW16    status;
BBoxRes tf_bbox;                /* b-box of TFS font */
BBoxRes plugin_bbox;            /* b-box encompassing all plugin fonts */
SL32     yes_plugins = 0;
SL32     ii, jj, nn;

    DBG("CGIFbound_box\n");

    /* This function finds the bounding box of the TFS font,
     * ORs it with the bounding box of the plugin set, calls comp_pix()
     * to get the transformation matrix from design units into pixels,
     * and returns the transformed bounding box (with a fudge factor included.
     * Must call BUCKfind() because comp_pix() requires pBucket as an argument.
     */

    {
        if ((status = IXget_fnt_index(FSA &if_state.fcCur)) != SUCCESS)
            goto BBOX_EXIT;
    }

    if ((status = BUCKfind(FSA TF_SENSITIVE, CREATE_BUCKET, &pBucket)) != SUCCESS)
        goto BBOX_EXIT;


    {   /* normal font (non-convergent) */

/* xxget_FontBBox() is an FST specific function that returns the TFS font
 * bounding box and design resolution in design units, with the composition
 * origin at (0,0) (the Intellifont b-box coordinates must be normalized.)
 * bbox_union() unions the TFS b-box and the plugin b-box, when applicable.
 */
    switch (pBucket->fst_type)
    {
#if IF_RDR
        case FC_IF_TYPE:
            if ((status = ifget_FontBBox(FSA pBucket, &tf_bbox)) != SUCCESS)
                goto BBOX_EXIT;
#if FCO_RDR
            /* IF font uses FCO plugins */
            if ((status = fco_get_FontBBox(FSA pBucket, 0, &plugin_bbox)) != SUCCESS)
                goto BBOX_EXIT;
#else
            plugin_bbox = IFplugin;
#endif  /* !FCO_RDR */
            yes_plugins = 1;
            fluffFactorY = fluffFactor = IF_FLUFF;
            DBG5("IF BBox in design units (%ld):  { %ld, %ld, %ld, %ld }\n",
                 tf_bbox.emRes, tf_bbox.BBox[0], tf_bbox.BBox[1], tf_bbox.BBox[2], tf_bbox.BBox[3]);
            break;
#endif  /**** IF_RDR ****/

#if TT_RDR
        case FC_TT_TYPE:
            if ((status = ttget_FontBBox(pBucket, &tf_bbox)) != SUCCESS)
                goto BBOX_EXIT;
#if FCO_RDR
            /* TT font uses FCO plugins */
            if ((status = fco_get_FontBBox(FSA pBucket, 0, &plugin_bbox)) != SUCCESS)
                goto BBOX_EXIT;
            yes_plugins = 1;
#else
#if TT_TTPLUG
            plugin_bbox = TTplugin;
            yes_plugins = 1;
#endif
#endif  /* !FCO_RDR */
            fluffFactorY = fluffFactor = TT_FLUFF;
            fScale = fpint2fp( ((SL32)tf_bbox.emRes) );
            break;
#endif  /**** TT_RDR ****/

#if PST1_RDR
        case FC_PST1_TYPE:
            if ((status = psget_FontBBox(pBucket, &tf_bbox)) != SUCCESS)
                goto BBOX_EXIT;
#if (IF_RDR && PS_IFPLUG)
            plugin_bbox = IFCOREplugin;
            yes_plugins = 1;
#endif
            fluffFactorY = fluffFactor = PS_FLUFF;
            fScale = fpint2fp( ((SL32)tf_bbox.emRes) );
            break;
#endif  /* PST1_RDR */

#if FCO_RDR
        case FC_FCO_TYPE:
            if ((status = fco_get_FontBBox(FSA pBucket, 1, &tf_bbox)) != SUCCESS)
                goto BBOX_EXIT;
            fluffFactorY = fluffFactor = FCO_FLUFF;
            yes_plugins = 0;    /* font bbox already includes plugin faces */
            break;
#endif  /* FCO_RDR */

        default:
            status = ERRfont_bbox;
            goto BBOX_EXIT;
    }   /*** end of switch (pBucket->fst_type) ***/
   }  /* not Convergent Font */

    if (yes_plugins)    /* Union of TFS bound box & plugin bound box */
        bbox_union(&tf_bbox, &plugin_bbox);      /* Modifies tf_bbox */

    DBG5("BBox in design units (%ld):  { %ld, %ld, %ld, %ld }\n",
         tf_bbox.emRes, tf_bbox.BBox[0], tf_bbox.BBox[1], tf_bbox.BBox[2], tf_bbox.BBox[3]);

    for (ii=0; ii<4; ii++)      /* convert to floating point */
        bboxDU_fp[ii] = fpint2fp((SL32)tf_bbox.BBox[ii]);

    /* Force fontcontext matching to fail so that comp_pix() is executed in full, 10-18-94 */
    if_state.cur_loc_fc.font_id = 0;
    if_state.cur_loc_fc.font_hdr =  (LPUB8)0;
    /* Do the same for system copy of fontcontext too. */
    if_state.pserver->cur_loc_fc.font_id = 0;
    if_state.pserver->cur_loc_fc.font_hdr = (LPUB8)0;
#if SLIM_FONTS
    if_state.chr_def_hdr.mirror_flags = 0;   /* Force comp_pix() to produce */
#endif                              /* a nonmirrored "if_state.m"  */

#if GRAYSCALING
    {
    /* If grayscale in on, it modifies the transformation matrix for doing
     * subpixel calculations. This would produce bogus values for the
     * bounding box which needs to return gray (super) pixel results.
     */
      UW16 saveFormat = if_state.fcCur.format;
      if (FC_ISGRAY(&if_state.fcCur)) {
          if_state.fcCur.format &= ~FC_OUTPUT_MASK;  /* turn off grayscale, temporarily */
          if_state.fcCur.format |= FC_BITMAP_TYPE;
      }
      if ((status = comp_pix(FSA &if_state.fcCur, pBucket)) != SUCCESS) {
          if_state.fcCur.format = saveFormat;  /* restore */
          goto BBOX_EXIT;
      }
      if_state.fcCur.format = saveFormat;  /* restore */
    }
#else  /* no GRAYSCALING */
    if ((status = comp_pix(FSA &if_state.fcCur, pBucket)) != SUCCESS)  /* set transformation matrix in if_state */
        goto BBOX_EXIT;
#endif
#if VLCOUTPUT   /* Return power of two needed to scale the bounding box */
    *pVLCpower = if_state.cs.VLCpower;
#endif

    /* This has to be done after comp_pix()! - 6-27-95 */
    if (pBucket->fst_type == FC_FCO_TYPE || pBucket->fst_type == FC_IF_TYPE)
        fScale = fpint2fp( ((SL32)if_state.x.pixel_size) );

    for (ii=0; ii<4; ii++)  /* matrix[] scales from design units to pixels */
        matrix[ii] = fpdiv(if_state.m[ii], fScale);

#ifdef AGFADEBUG
    DBG("Transformation Matrix:  ");
    fpprint(FSA matrix[0]);
    fpprint(FSA matrix[1]);
    fpprint(FSA matrix[2]);
    fpprint(FSA matrix[3]);
    DBG("\n");
#endif  /* AGFADEBUG */

    /* Transform the 4 corners of the font bbox. Find the
     * new min and max x, y from the 4 transformed points. */
    for (nn=0, ii=0; ii<4; ii += 2)
    {
        for (jj=1; jj<4; jj += 2, nn++)
        {
            bboxpt[nn].x = fp2word( fpadd( fpmul( bboxDU_fp[ii], matrix[0] ),
                                           fpmul( bboxDU_fp[jj], matrix[2] ) ) );
            bboxpt[nn].y = fp2word( fpadd( fpmul( bboxDU_fp[ii], matrix[1] ),
                                           fpmul( bboxDU_fp[jj], matrix[3] ) ) );
        }
    }

/* Add fudge factor to account for roundoff or truncation when
 * converting floating point to integer. The integer bounding box shall in
 * no case be smaller than the f.p. bbox.
 */
    FontBBox[0] = FontBBox[1] = MAX_WORD;
    FontBBox[2] = FontBBox[3] = MIN_WORD;
    for (ii=0; ii<4; ii++)
    {
        if (bboxpt[ii].x - (fluffFactor + 1) < FontBBox[0])
            FontBBox[0] = bboxpt[ii].x - (fluffFactor + 1);
        if (bboxpt[ii].y - (fluffFactorY + 1) < FontBBox[1])
            FontBBox[1] = bboxpt[ii].y - (fluffFactorY + 1);
        if (bboxpt[ii].x + (fluffFactor + 1) > FontBBox[2])
            FontBBox[2] = bboxpt[ii].x + (fluffFactor + 1);
        if (bboxpt[ii].y + (fluffFactorY + 1) > FontBBox[3])
            FontBBox[3] = bboxpt[ii].y + (fluffFactorY + 1);
    }

    status = SUCCESS;


BBOX_EXIT:
    return status;
}
/* CGIFFbound_box */

/*
 * bbox_union
 *
 * Unions two b-box structures. If the design resolutions are
 * different, converts the plugin b-box to tfs units.
 * Modifies *tfs
 */
#if defined (ANSI_DEFS)
MLOCAL VOID  bbox_union( BBoxRes* tfs, BBoxRes* plug )
#else
MLOCAL VOID  bbox_union(tfs, plug)
  BBoxRes *tfs, *plug;
#endif /* ANSI_DEFS */
{
    SL32   ii;

    if (!plug->emRes)  /* If there are no plugins, then exit. */
        return;

    for (ii=0; ii<4; ii++)
    {
        if (tfs->emRes != plug->emRes)
        {
            plug->BBox[ii] = (SL32)((plug->BBox[ii] * (SL32)tfs->emRes) / plug->emRes);
            if (ii < 2)          /* After converting units, round */
                plug->BBox[ii]--;
            else
                plug->BBox[ii]++;
        }

        if (ii < 2) {
            if (plug->BBox[ii] < tfs->BBox[ii])
                tfs->BBox[ii] = plug->BBox[ii];
        }
        else {
            if (plug->BBox[ii] > tfs->BBox[ii])
                tfs->BBox[ii] = plug->BBox[ii];
        }
    }
}  /* bbox_union */


#if PST1_RDR

/* psget_FontBBox
 *
 * Returns font bbox and design resolution.
 * Do full implementation later - 1/29/93.
 */
#if defined (ANSI_DEFS)
MLOCAL UW16  psget_FontBBox( PBUCKET pBucket, BBoxRes* basefont)
#else
MLOCAL UW16  psget_FontBBox( pBucket, basefont )
PBUCKET pBucket;
BBoxRes* basefont;
#endif
{
   /* If font bounding box information has not been stored,
    * initialize it to -2000,, -2000, 2000, 2000, 1000
    */

    if (!pBucket->p.ps.FontBBox[0] && !pBucket->p.ps.FontBBox[1] &&
        !pBucket->p.ps.FontBBox[2] && !pBucket->p.ps.FontBBox[3])
    {
       basefont->BBox[0] = basefont->BBox[1] = -2000;
       basefont->BBox[2] = basefont->BBox[3] = 2000;
    }
    else
    {
       basefont->BBox[0] = pBucket->p.ps.FontBBox[0];
       basefont->BBox[1] = pBucket->p.ps.FontBBox[1];
       basefont->BBox[2] = pBucket->p.ps.FontBBox[2];
       basefont->BBox[3] = pBucket->p.ps.FontBBox[3];
    }
    basefont->emRes = 1000;
    return SUCCESS;
}
#endif  /* PST1_RDR */


#if IF_PCLEOI

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFbbox_IFPCLEOchar( FSP LPUB8 pchar_data,
                                 LPUB8 pfont_hdr, LPUW16 badCharList )
#else
UW16 CGENTRY CGIFbbox_IFPCLEOchar( pchar_data, pfont_hdr, badCharList )
   LPUB8   pchar_data;
   LPUB8   pfont_hdr;
   LPUW16  badCharList;
#endif /* ANSI_DEFS */
{
    SL32  ii;
    SL32  numMissing = 0;
    SL32  numPieces;
    SW16 xmin, ymin, xmax, ymax;
    LPUW16 pchr;

    if (pfont_hdr[2] != CGIFP_IF_SCALABLE || pchar_data[0] != CGIFP_IF_SCALABLE)
    {
      return (UW16)0xFFFF;      /* Not Intellifont! */
    }

    switch (pchar_data[3])
    {
      case 3:         /* Intellifont Scalable Character */
        bbox_SimpleChar(pchar_data, &xmin, &ymin, &xmax, &ymax);
        break;

      case 4:         /* Intellifont Scalable Compound Character */
        numPieces = pchar_data[6];      /* only 1 byte! */
        pchr = (LPUW16)(pchar_data + 8);
        for (ii=0; ii<numPieces; ii++)  /* analyze each component */
        {
            UW16 charcode;
            LPUB8 componentPtr;
            charcode = *pchr++;
            componentPtr = PCLEO_charptr(FSA pfont_hdr, charcode);
            if (!componentPtr)
            {
                badCharList[numMissing++] = charcode;
                if (numMissing == CGIFP_MAX_BADCHARS)
                {
                  return (UW16)numMissing;
                }
                else
                    pchr += 2;
            }
            else
            {
                if (componentPtr[0] != CGIFP_IF_SCALABLE || componentPtr[3] != 3)
                {
                  return 0xFFFF;      /* Components of a c.c. cannot */
                }
                                        /* themselves be compound.     */
                bbox_SimpleChar(componentPtr, &xmin, &ymin, &xmax, &ymax);
                xmin += (SW16)(*pchr); xmax += (SW16)(*pchr++); /* x-offset */
                ymin += (SW16)(*pchr); ymax += (SW16)(*pchr++); /* y-offset */
            }
        }       /* for (ii ...  */
        break;

      default:
        return (UW16)0xFFFF;    /* corrupt data */
    }
    if (numMissing)
    {
      return (UW16)numMissing;
    }

    /* Union the character's bounding box with the 4 words in the PCLEO hdr. */
    bbox_union_1( xmin, ymin, xmax, ymax,
                  (LPSW16)(pfont_hdr+TEXT_WIDTH),
                  (LPSW16)(pfont_hdr+TEXT_HEIGHT),
                  (LPSW16)(pfont_hdr+CELL_WIDTH),
                  (LPSW16)(pfont_hdr+CELL_HEIGHT) );
    return SUCCESS;
}


#if defined (ANSI_DEFS)
MLOCAL VOID bbox_SimpleChar( LPUB8 pchar_data,
                             LPSW16 xmin, LPSW16 ymin,
                             LPSW16 xmax, LPSW16 ymax )
#else
MLOCAL VOID bbox_SimpleChar( pchar_data, xmin, ymin, xmax, ymax )
  LPUB8   pchar_data;
  LPSW16  xmin, ymin, xmax, ymax;
#endif /* ANSI_DEFS */
{
    LPSW16 pMetrics;
    SW16   origin_x, origin_y;

    pMetrics = (LPSW16)(pchar_data + 4 + *(LPUW16)(pchar_data + 6));
    origin_x = *(pMetrics + 4);
    origin_y = *(pMetrics + 5);
    *xmin = *pMetrics - origin_x;
    *ymin = *(pMetrics+1) - origin_y;
    *xmax = *(pMetrics+2) - origin_x;
    *ymax = *(pMetrics+3) - origin_y;
}


#if defined (ANSI_DEFS)
MLOCAL VOID bbox_union_1( SW16 xmin, SW16 ymin, SW16 xmax, SW16 ymax,
                          LPSW16 pxmin, LPSW16 pymin, LPSW16 pxmax, LPSW16 pymax )
#else
MLOCAL VOID bbox_union_1( xmin, ymin, xmax, ymax, pxmin, pymin, pxmax, pymax )
   SW16   xmin,  ymin,  xmax,  ymax;
   LPSW16 pxmin, pymin, pxmax, pymax;
#endif /* ANSI_DEFS */
{
if (xmin < *pxmin)  *pxmin = xmin;
if (ymin < *pymin)  *pymin = ymin;
if (xmax > *pxmax)  *pxmax = xmax;
if (ymax > *pymax)  *pymax = ymax;
}

#endif  /* IF_PCLEOI */

#endif  /* FONTBBOX */

/*----------------------*/
/*    CGIFchIdptr       */
/*----------------------*/
/*  Store a pointer to the chId in IF_STATE. This will be used if
 *  symbol set mapping has been removed (NO_SYMSET_MAPPING).
 */
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFchIdptr(FSP VOID *chId, VOID *PSchar_name)
#else
UW16 CGENTRY CGIFchIdptr(chId, PSchar_name)
    VOID      *chId;
    VOID      *PSchar_name;
#endif /* ANSI_DEFS */
{
    UW16      status;

    status = SUCCESS;

    DBG1("CGIFchIdptr(%lu)\n", chId);

    if_state.chIdptr = chId;
#if PST1_RDR
    if_state.PSchar_name = PSchar_name;

    /* 08-16-01 jfd 
     * 
     * Map the PS char name to a CG number
     *
     */
    if (FC_ISPST1(&if_state.fcCur))
    {
        UW16 mapidx;

        mapidx = psnameToIndex((LPSB8)PSchar_name);
        if (mapidx)
            if_state.chIdptr = IndexToCgid(mapidx);
        else
            status = ERR_psi_idx2psname;
    }

#endif  /* PST1_RDR */

    return status;
}


#if defined (ANSI_DEFS)
VOID CGENTRY CGIFfont_access(FSP UW16 font_access)
#else
VOID CGENTRY CGIFfont_access(font_access)
    UW16      font_access;
#endif /* ANSI_DEFS */
{
    if_state.font_access = font_access;
}

#if (TT_ROM || TT_DISK || TT_ROM_ACT)

/**************************************************************************/
/* Function:    CGIFtt_query - API to retrieve the buffer containing the  */
/*              whole TrueType table entry, based on a tag id and TTC     */
/*              index (if applicable).  This routine assumes that the     */
/*              caller knows the structure of the table being returned.   */
/*                                                                        */
/*              1st call - pBuffer should be NULL; will get the size      */
/*              of the requested table                                    */
/*              2nd call - fills pBuffer with the table                   */
/*                                                                        */
/* Parameters:  pFont(I) - ptr to pathname (disk) or truetype font in rom */
/*              uTagKey(I) - 4-byte identifier for the TT table           */
/*              uTTCindex(I) - index into TTC array of table directories  */
/*              uSize(O/I) - size of the tag's table                      */
/*              pBuffer(O) - buffer of size uSize to hold the table entry */
/*                                                                        */
/* Return:  UW16 - Did the function successfully retrieve the TT tag      */
/*          information from the font tables; SUCCESS or FAILURE.         */
/* Created: ks - December 27, 1999                                        */
/**************************************************************************/

#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFtt_query (FSP LPUB8 pFont, UL32 uTagKey, UW16 uTTCIndex,
                            LPUL32 uSize, LPUB8 pBuffer )
#else
UW16  CGENTRY CGIFFtt_query (pFont, uTagKey, uTTCIndex, uSize, pBuffer )
LPUB8 pFont;
UL32 uTagKey;
UW16 uTTCIndex;
LPUL32 uSize;
LPUB8 pBuffer;
#endif /* ANSI_DEFS */
{
    SW16 status = SUCCESS;
    BOOLEAN bDisk_access = if_state.font_access == DISK_ACCESS;
#if TT_DISK
    INTG nFile=0;
#endif

    if( bDisk_access )    
    {
#if TT_DISK

        /* Open the file */
        if ((nFile = OPEN((FILECHAR*)pFont, O_READFLAGS) ) == -1)
        {
            DBG1("Error - can't open file %s\n", pFont);
            return (UW16)FAILURE;
        }

        pFont = (LPUB8)nFile;
#endif  /* TT_DISK */
    }

    /* This is the 1st call if pBuffer is NULL.                */
    /* Get the size of the table to retrieve based on uTagKey. */

    if( pBuffer == NULL )
    {
        *uSize = tt_GetTagSize( FSA pFont, uTagKey, uTTCIndex );
        
        if( (*uSize) == 0 )
        {
            DBG1( "Key %ld is not supported\n", uTagKey );
            status = FAILURE;
        }  /* !uSize */
        
    }  /* pBuffer == NULL */
    else
    {
        /* Get the requested table and copy into the provided buffer. */
        status = (SW16)tt_GetTagBuffer( FSA pFont, uTagKey, uTTCIndex, *uSize, pBuffer);
    }

    /* close the file */

    if( bDisk_access )
    {
#if TT_DISK
        CLOSE (nFile);
#endif
    }

    return (UW16)status;

}    /* CGIFtt_query() */

#if (CACHE || CHAR_HANDLE) && DIRECT_TT_TABLE_ACCESS
/****************************************************************************/
/* Function:    CGIFtt_query_direct - API to retrieve a pointer to the      */
/*              requested TrueType table entry, based on font, tag id and   */
/*              TTC index (if applicable).  This routine assumes that the   */
/*              caller knows the structure of the table being returned.     */
/*              It also assumes that the caller has previously called the   */
/*              function CGIFfont_access() to set the proper I/O mode (ROM  */
/*              or DISK).                                                   */
/*                                                                          */
/* Parameters:  pFont(I) - ptr to pathname (disk) or truetype font in rom   */
/*              uTagKey(I) - 4-byte identifier for the TT table             */
/*              uTTCindex(I) - index into TTC array of table directories    */
/*              uSize(O/I) - size of the tag's table                        */
/*              pBuffer(O) - ptr to tag's table                             */
/*                                                                          */
/* Return:  UW16 - Did the function successfully retrieve the TT tag        */
/*          information from the font tables; SUCCESS or FAILURE.           */
/****************************************************************************/
#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFtt_query_direct (FSP LPUB8 pFont, UL32 uTagKey, UW16 uTTCIndex,
                            LPUL32 uSize, LPLPUB8 pBuffer )
#else
UW16  CGENTRY CGIFFtt_query_direct (pFont, uTagKey, uTTCIndex, uSize, pBuffer )
LPUB8 pFont;
UL32 uTagKey;
UW16 uTTCIndex;
LPUL32 uSize;
LPLPUB8 pBuffer;
#endif /* ANSI_DEFS */
{
    SW16 status = SUCCESS;
    BOOLEAN bDisk_access = if_state.font_access == DISK_ACCESS;
#if TT_DISK
    INTG nFile=0;
#endif
    DIRECT_ACCESS_ENTRY *p;
    UL32 table_size;
    LPUB8 disk_rom_ptr = pFont;
    MEM_HANDLE hBuffer;
    LPUB8 Buffer;

    *uSize = 0L;
    *pBuffer = (LPUB8)NULL;

    /* Search list for requested table (font + tag + ttc index). */
    if ( (p = ttTBL_find_font(FSA pFont, uTagKey, uTTCIndex)) != (DIRECT_ACCESS_ENTRY *)NULL)
    {
        /* Table found in list. Increment reference counter. */
        p->num_refs++;

        /* Return table size and ptr. */
        *uSize = p->size;
        *pBuffer = p->pTable;
        return SUCCESS;
    }

    /* Table not found in list. Extract table from font. */
#if TT_DISK
    if( bDisk_access )    
    {
        /* Disk access. Open the file */
        if ((nFile = OPEN((FILECHAR*)pFont, O_READFLAGS) ) == -1)
        {
            DBG1("Error - can't open file %s\n", pFont);
            return (UW16)FAILURE;
        }
        disk_rom_ptr = (LPUB8)nFile;
    }
#endif  /* TT_DISK */

    /* Get the size of the table to retrieve based on uTagKey. */
    table_size = tt_GetTagSize( FSA disk_rom_ptr, uTagKey, uTTCIndex );
    if( (table_size) == 0 )
    {    
        status = FAILURE;
        DBG1( "Key %ld is not supported\n", uTagKey );
        goto cleanup;
    }  /* !table_size */


    /* Allocate a buffer for the requested table. */
    if ( bDisk_access
#if TT_ROM_ACT
            || ACT_RA_DECOMP_isACT( pFont )
#endif    /* TT_ROM_ACT */
            )
    {
        hBuffer = (MEM_HANDLE)BUFalloc(FSA table_size);
        if (!hBuffer)
        {
            status = FAILURE;
            DBG1( "Couldn't allocate %ld bytes for TT table\n", table_size );
            goto cleanup;
        }
        Buffer = (LPUB8)MEMptr(hBuffer);

        /* Get the requested table and copy into the provided buffer. */
        status = (SW16)tt_GetTagBuffer( FSA disk_rom_ptr, uTagKey, uTTCIndex, table_size, Buffer);
        if (status == FAILURE)
        {
            BUFfree(FSA hBuffer);
            goto cleanup;
        }
    }
    else
    {
        UL32 table_offset;

        table_offset = tt_GetTagOffset( FSA disk_rom_ptr, uTagKey, uTTCIndex );
        if (!table_offset)
        {
            DBG1( "Tag %8lx not found in font", uTagKey);
            return (UW16)FAILURE;
        }
        Buffer = (LPUB8)(disk_rom_ptr + table_offset);
        hBuffer = (MEM_HANDLE)NIL_MH;
    }

    /* Find available slot in list to store table info. */
    if ( (p = ttTBL_find_slot(FSA0)) == (DIRECT_ACCESS_ENTRY *)NULL)
        return (UW16)FAILURE;

    /* Add entry to list. */
#if TT_DISK
    if (bDisk_access)
    {
        MEM_HANDLE hpf;

        hpf = (MEM_HANDLE)BUFalloc(FSA STRLEN(pFont) + 1);
        if (!hpf)
        {
            status = FAILURE;
            BUFfree(FSA hBuffer);
            DBG1( "Couldn't allocate %d bytes for TT table\n", STRLEN(pFont) );
            goto cleanup;
        }
        p->pFont = (LPUB8)MEMptr(hpf);
        p->hFont = hpf;
        STRCPY(p->pFont, pFont);
    }
    else
#endif
    {
        p->pFont = pFont;
        p->hFont = (MEM_HANDLE)NIL_MH;
    }
    p->pTable = Buffer;
    p->hTable = hBuffer;
    p->size = table_size;
    p->tag = uTagKey;
    p->ttc_index = uTTCIndex;
    p->num_refs = 1;
#if TT_ROM_ACT
    /* ACT font processing requires that a buffer be allocated */
    if (ACT_RA_DECOMP_isACT( pFont ))
        p->buff_allocd = TRUE;
    else
#endif    /* TT_ROM_ACT */
    p->buff_allocd = bDisk_access;

    /* Return size and ptr to table. */
    *uSize = p->size;
    *pBuffer = p->pTable;

    /* if_state.datables->num_entries++; */ 
    status = SUCCESS;

cleanup:
#if TT_DISK
    if( bDisk_access )
    {
        /* Disk access. Close the file. */
        CLOSE (nFile);
    }
#endif
    return status;
}

/****************************************************************************/
/* Function:    CGIFtt_query_direct_free - API to free a TrueType table     */
/*              based on a ptr returned by CGIFtt_query_direct() call and   */
/*              the number of outstanding references to the table. The list */
/*              of queried TT tables is searched for the requested table    */
/*              and if found, its reference count is decremented. If the    */
/*              count goes to 0, that entry is marked as "unused" and can   */
/*              be reused for ensuing tables belonging to that font. If the */
/*              count goes to 0 and a buffer had been allocated for the     */
/*              table, the function frees the buffer.                       */
/*                                                                          */
/* Parameters:  pTable(I) - ptr to TT table to be freed                     */
/*                                                                          */
/* Return:  UW16 - Did the function successfully free the TT table;         */
/*          SUCCESS or FAILURE.                                             */
/****************************************************************************/
#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFtt_query_direct_free (FSP LPUB8 pTable )
#else
UW16  CGENTRY CGIFFtt_query_direct_free (pTable )
LPUB8 pTable;
#endif /* ANSI_DEFS */
{
    DIRECT_ACCESS_ENTRY *p;

    /* Search list for requested table. */
    if ( (p = ttTBL_find_table(FSA pTable)) != (DIRECT_ACCESS_ENTRY *)NULL)
    {
        /* Table found in list. */ 
        if (p->num_refs)
        {
            /* Decrement reference counter. */
            p->num_refs--;

            /* If there are no outstanding references assigned to table,
             * mark the slot as available.
             */
            if (!p->num_refs)
            {
                p->num_refs = TT_TABLE_SLOT_UNUSED;

                /* If buffer had been allocated for the table, free it. */
                if (p->buff_allocd)
                {
                    BUFfree(FSA p->hTable);
                    p->hTable = (MEM_HANDLE)NIL_MH;
                    BUFfree(FSA p->hFont);
                    p->hFont = (MEM_HANDLE)NIL_MH;
                }
            }
            return SUCCESS;
        }
        /* There are no outstanding references assigned to table. */
        return (UW16)FAILURE;
    }
    /* Table not found in list. */
    return (UW16)FAILURE;
}
#endif

/******************

    CGIFFtt_cmap_query()

    Cloned from CGIFtt_query() - special-purpose query function that returns a 
    list of all the "cmap" tables in a TT/TTC/ACT font, as a set of pairs
    (platformId, specificId) - see the structure typedefs CMAP_QUERY and 
    CMAP_ENTRY in /sys/inc/if_type.h.

    Limitations - the return structure is hardcoded with a maximum number of 
    "cmap" subtables (MAX_NUM_CMAP, currently set to 20). Just in case this is
    too small, a (non-fatal) error code ERR_TT_TOO_MANY_CMAPS will be
    returned if the font has more than MAX_NUM_CMAP subtables - if this error
    is ever seen, we can decide whether to increase MAX_NUM_CMAP, or whether
    to go to a more-dynamic allocation scheme for this function.

    (sandra, Dec 2000)

******************/

#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFtt_cmap_query (FSP UB8 *pFont, UW16 uTTCIndex, CMAP_QUERY *ret)
#else
UW16  CGENTRY CGIFFtt_cmap_query (pFont, uTTCIndex, ret)
UB8 *pFont;
UW16 uTTCIndex;
CMAP_QUERY *ret;
#endif /* ANSI_DEFS */
{
    SW16 status = SUCCESS;
    BOOLEAN bDisk_access = if_state.font_access == DISK_ACCESS;
#if TT_DISK
    INTG nFile=0;
#endif 
    
    UL32 uTagKey = tag_CharToIndexMap;    /* valid for both byte-orders? */
    UL32 uSize;
    UW16 idx;
    MEM_HANDLE hCmap = NIL_MH;

    CMAP_HEAD *cmapBuf;
    CMAP_SUBTABLE subtab;

    if( bDisk_access )    
    {
#if TT_DISK
        /* Open the file */

        if ((nFile = OPEN((FILECHAR*)pFont, O_READFLAGS) ) == -1)
        {
            DBG1("CGIFtt_cmap_query error - can't open file %s\n", pFont);
            return (UW16)FAILURE;
        }

        pFont = (LPUB8)nFile;
#endif  /* TT_DISK */
    }

    /* Get the size of the cmap table to retrieve */

    uSize = tt_GetTagSize( FSA pFont, uTagKey, uTTCIndex );
    if( !uSize )
    {
        DBG("CGIFtt_cmap_query - cmap table not found in font\n");
        status = FAILURE;
    }
    else
    {
        /* only need to read in header portion of cmap table */
        /* also need to test for (CMAP_HEAD size > usize), however */
        if (uSize > sizeof(CMAP_HEAD))
            uSize = sizeof(CMAP_HEAD);

        if ((hCmap = BUFalloc(FSA (SL32)uSize)) == (MEM_HANDLE)NULL)
        {                                                                       
            /* put an out-of-memory debug here? */
            DBG("CGIFtt_cmap_query error: out of memory\n");
            status = FAILURE;
        }
        else
        {
            cmapBuf = (CMAP_HEAD *)MEMptr(hCmap);
        
            /* Get the requested table and copy into the provided buffer. */
            status = (SW16)tt_GetTagBuffer( FSA pFont, uTagKey, uTTCIndex, 
                uSize, (UB8 *)cmapBuf);

            /* now read the header info and parse it */
            ret->version = SWAPW(cmapBuf->version);
            ret->numCmap = SWAPW(cmapBuf->numCmap); 
            
            /* make sure we don't overflow allocated structure */
            /* if too many subtables, then return as much info as possible: */
            /* thus, ERR_TT_TOO_MANY_CMAPS is a (nonfatal) semi-error */  
            if (ret->numCmap > MAX_NUM_CMAP)
            {
                ret->numCmap = MAX_NUM_CMAP;
                status = ERR_TT_TOO_MANY_CMAPS;
            }
                    
            for (idx = 0; idx < ret->numCmap; idx ++)
            {
                subtab = cmapBuf->subtable[idx];
                ret->entry[idx].platId = SWAPW(subtab.platId);         
                ret->entry[idx].specId = SWAPW(subtab.specId);         
            }
        }
    }

    /* close the file */

    if( bDisk_access )
    {
#if TT_DISK
        CLOSE (nFile);
#endif
    }
    
    /* free the temporary buffer for the cmap table */
    if (hCmap)
        BUFfree(FSA (MEM_HANDLE)(hCmap));

    return status;

}    /* CGIFFtt_cmap_query() */

/******************

    CGIFFtt_name_query()

    Cloned from CGIFtt_cmap_query() - special-purpose query function that returns 
    the font name, font family name, and copyright string in a TT/TTC/ACT font 
    (as given in the "name" table) - see the structure typedef NAME_QUERY in 
    /sys/inc/if_type.h.

    Limitations - each of the fields in the return structure is hardcoded with a 
    maximum length - if the data in the file exceeds that length, the corresponding
    BOOLEAN in the return structure is set. These maximum lengths are defined in 
    /sys/inc/if_type.h, and can be modified by the implementor, if necessary.

    (sandra, Oct 2002)

******************/

#if defined (ANSI_DEFS)
UW16  CGENTRY CGIFFtt_name_query (FSP UB8 *pFont, UW16 uTTCIndex, NAME_QUERY *ret)
#else
UW16  CGENTRY CGIFFtt_name_query (pFont, uTTCIndex, ret)
UB8 *pFont;
UW16 uTTCIndex;
NAME_QUERY *ret;
#endif /* ANSI_DEFS */
{
    SW16 status = SUCCESS;
    BOOLEAN bDisk_access = if_state.font_access == DISK_ACCESS;
#if TT_DISK
    INTG nFile=0;
#endif 

    UL32 uTagKey = tag_NamingTable;
    UL32 uSize;
    MEM_HANDLE hName = NIL_MH;
    UB8 *nameBuf, *ptr;
    UW16 numRec, strOff;
    SL32 ii, jj;

    if( bDisk_access )    
    {
#if TT_DISK
        /* Open the file */

        if ((nFile = OPEN((FILECHAR*)pFont, O_READFLAGS) ) == -1)
        {
            DBG1("CGIFtt_name_query error - can't open file %s\n", pFont);
            return (UW16)FAILURE;
        }

        pFont = (LPUB8)nFile;
#endif  /* TT_DISK */
    }
    
    /* Get the size of the name table to retrieve */

    uSize = tt_GetTagSize( FSA pFont, uTagKey, uTTCIndex );
    if( !uSize )
    {
        DBG("CGIFtt_name_query - name table not found in font\n");
        return (UW16)FAILURE;
    }

    if ((hName = BUFalloc(FSA (SL32)uSize)) == (MEM_HANDLE)NULL)
    {                                                                       
        DBG("CGIFtt_name_query error: out of memory\n");
        return (UW16)FAILURE;
    }

    nameBuf = (UB8 *)MEMptr(hName);

    /* Get the requested table and copy into the provided buffer. */
    status = (SW16)tt_GetTagBuffer( FSA pFont, uTagKey, uTTCIndex, uSize, (UB8 *)nameBuf);

    numRec = GET_xWORD((nameBuf + NAME_NUM_REC));     /* nr of records to follow  */
    strOff = GET_xWORD((nameBuf + NAME_OFF_TO_STRS)); /* offset to string storage */
    ptr = nameBuf + NAME_NAMERECS;                  /* The NameRecords */

    ret->copyright[0] = 0;
    ret->font_family_name[0] = 0;
    ret->font_name[0] = 0;
    ret->copyright_too_long = FALSE;
    ret->font_family_name_too_long = FALSE;
    ret->font_name_too_long = FALSE;

    /* extract the font name, family name and copyright data from the "name" table */
    for (ii=0; ii<numRec; ii++, ptr += NAME_SIZE_NAMEREC)
    {
        if ((GET_xWORD((ptr+NAME_TAB_PLATID))) == MSFT_ENC  &&
            (GET_xWORD((ptr+NAME_TAB_LANGID))) == US_ENGL )
        {
            UB8 *strPtr = nameBuf + strOff + GET_xWORD((ptr+NAME_TAB_STROFF));
            SW16 strLen = GET_xWORD((ptr+NAME_TAB_STRLEN)) >> 1;

            if ((GET_xWORD((ptr+NAME_TAB_NAMEID))) == name_Family)
            {
                /* if font family name length is larger than pre-allocated
                 * buffer length, set "too_long" flag
                 */
                if (strLen > MAX_FONT_FAMILY_NAME_LEN - 1)
                    ret->font_family_name_too_long = TRUE;

                /* strings are in Unicode - 2 bytes per char */

                for (jj=0,strPtr++; jj<strLen; jj++) 
                {
                    if (jj == MAX_FONT_FAMILY_NAME_LEN - 1)
                        break;
                    ret->font_family_name[jj] = *strPtr;
                    strPtr += 2;
                }
                ret->font_family_name[jj] = 0;
            }
            else if ((GET_xWORD((ptr+NAME_TAB_NAMEID))) == name_FullName)
            {
                /* if font name length is larger than pre-allocated
                 * buffer length, set "too_long" flag
                 */
                if (strLen > MAX_FONT_NAME_LEN - 1)
                    ret->font_name_too_long = TRUE;

                /* strings are in Unicode - 2 bytes per char */

                for (jj=0,strPtr++; jj<strLen; jj++)
                {
                    if (jj == MAX_FONT_NAME_LEN - 1)
                        break;
                    ret->font_name[jj] = *strPtr;
                    strPtr += 2;
                }
                ret->font_name[jj] = 0;
            }
            else if ((GET_xWORD((ptr+NAME_TAB_NAMEID))) == name_Copyright)
            {
                /* if copyright length is larger than pre-allocated
                 * buffer length, set "too_long" flag
                 */
                if (strLen > MAX_COPYRIGHT_LEN - 1)
                    ret->copyright_too_long = TRUE;

                /* strings are in Unicode - 2 bytes per char */

                for (jj=0,strPtr++; jj<strLen; jj++)
                {
                    if (jj == MAX_COPYRIGHT_LEN - 1)
                        break;
                    ret->copyright[jj] = *strPtr;
                    strPtr += 2;
                }
                ret->copyright[jj] = 0;
            }

        /* exit loop once we have all names */
        if (ret->font_name[0] && ret->font_family_name[0] && ret->copyright[0])
            break;
        }
    }

    /* close the file */

    if( bDisk_access )
    {
#if TT_DISK
        CLOSE (nFile);
#endif
    }
    
    /* free the temporary buffer for the name table */
    if (hName)
        BUFfree(FSA (MEM_HANDLE)(hName));

    return status;

}    /* CGIFFtt_name_query() */

#endif  /* TT_ROM || TT_DISK || TT_ROM_ACT */


/************************************************************
 
    CGIFwhat_version()

    Returns UFST version information to the user in the UFST_VERSION_INFO structure (defined in cgif.h). 
    
    The version information is in three parts:
        major version number (a small integer > 0),
        minor version number (a small integer >= 0),
        a patchstring (which may contain descriptive information, or may be null).

    Typically, the patchstring will be null for a regular UFST release.

    The patchstring can be up to PATCHSTRING_LEN characters long - this value is defined in cgif.h. 

*************************************************************/

#define UFST_VERSION_MAJOR 4
#define UFST_VERSION_MINOR 7

CONST FILECHAR ufst_version_patchstring[] = "";

#if defined (ANSI_DEFS)
VOID CGENTRY CGIFwhat_version(UFST_VERSION_INFO *ret)
#else
VOID CGENTRY CGIFwhat_version(ret)
    UFST_VERSION_INFO *ret;
#endif /* ANSI_DEFS */
{
    ret->major_version = UFST_VERSION_MAJOR;
    ret->minor_version = UFST_VERSION_MINOR;
    if (STRLEN(ufst_version_patchstring) > 0)
        STRCPY(ret->patchstring, ufst_version_patchstring);
    else
        ret->patchstring[0] = 0;
}

/* access functions for if_state.trace_sw debug switch */

#if defined (ANSI_DEFS)
VOID UFST_debug_on(FSP0)
#else
VOID UFST_debug_on()
#endif
{
    if_state.trace_sw = 1;
}

#if defined (ANSI_DEFS)
VOID UFST_debug_off(FSP0)
#else
VOID UFST_debug_off()
#endif
{
    if_state.trace_sw = 0;
}

#if defined (ANSI_DEFS)
SW16 UFST_get_debug(FSP0)
#else
SW16 UFST_get_debug()
#endif
{
    return (if_state.trace_sw);
}

#if TT_RDR
/*-------------------------------------------------------------
    CGIFFget_kern_value

    Input:
        tableBuffer = pointer to TrueType "kern" table 
        id1 = glyph index of 1st char in kerning pair
        id2 = glyph index of 2nd char in kerning pair

    Returns:
        kerning adjustment for <id1, id2> (if pair found in "kern" table)
        0 (if pair not found in "kern" table)
     
-------------------------------------------------------------*/

#define LEFT 0
#define RIGHT 1
#define VALUE 2
 
#if defined (ANSI_DEFS)
SW16 CGENTRY CGIFFget_kern_value(FSP UB8 *tableBuffer, UL32 id1, UL32 id2)
#else
SW16 CGENTRY CGIFFget_kern_value(tableBuffer, id1, id2 )
UB8 *tableBuffer;
UL32 id1, id2;
#endif
{
    UW16 *bufPtr, nTables, version, length, coverage, nPairs, searchRange, entrySelector, rangeShift;
    UW16 i;
    UW16 *lo, *mid, *hi, n;
    UL32 k;
    UL32 key, try_key;
   
    bufPtr = (UW16*)tableBuffer;

    /* read in table */
    bufPtr++;
    nTables = SWAPW(*bufPtr);
    bufPtr++;

    /* loop through the subtables, only want version 0 */
    for( i = 0; i < nTables; i++ )
    {
        version = SWAPW(*bufPtr);
        bufPtr++;
        length = SWAPW(*bufPtr);
        bufPtr++;
        if( version != 0 )
            bufPtr += length;
    }
    
    /* read in table header, only really use some of these values */
    coverage = SWAPW(*bufPtr);
    bufPtr++;
    nPairs = SWAPW(*bufPtr);
    bufPtr++;
    searchRange = SWAPW(*bufPtr);
    bufPtr++;
    entrySelector = SWAPW(*bufPtr);
    bufPtr++;
    rangeShift = SWAPW(*bufPtr);
    bufPtr++;

    key = ((UL32)id1 << 16) | id2;
    lo = bufPtr;        /* pointer to kpv[0] */
    n = nPairs;    /* number of entries */
    hi = lo + (n-1)*3;        /* pointer to the last entry == kpv[n-1] */

    while (lo <= hi)
    {
        /* for integers P, Q, K:
        *    lo = base + 3P
        *    hi = base + 3Q
        *    hi - lo == 3Q - 3P == 3(P-Q) == 3K
        *    want mid = lo + 3(K/2)
        */
        k = (hi - lo)/3;
        mid = lo + 3*(k/2);
        try_key = SWAPW(mid[LEFT]);
        try_key = (try_key << 16) | SWAPW(mid[RIGHT]);
        if (key < try_key)
            hi = mid - 3;
        else if (key > try_key)
            lo = mid + 3;
        else
        {
            return ((SW16) SWAPW(mid[VALUE]));
//            break;
        }
    }
    return (0);        /* no kerning value found */

}    /* CGIFFget_kern_value */


/*--------------------------------------------------------------------*/

#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFchar_map(FSP UL32 chId, UW16 *glyph_index)
#else
UW16 CGENTRY CGIFFchar_map(chId, glyph_index)
    UL32 chId;
    UW16 *glyph_index;
#endif /* ANSI_DEFS */
{
    UW16 status = 0;
    PBUCKET bucket;
    fs_GlyphInfoType *ttOutput;

    status = IXget_fnt_index(FSA &if_state.fcCur);
    if(status)
        return status;
    status = IXsetup_chr_def(FSA chId, if_state.chr_def, &bucket);
    if(status)
        return status;
    ttOutput = (fs_GlyphInfoType*)MEMptr(bucket->p.tt.buffInfo);
    if(ttOutput)
        *glyph_index = ttOutput->glyphIndex;
    else
        status = ERR_find_cgnum;
    return status;
}

/*--------------------------------------------------------------------*/
#if defined (ANSI_DEFS)
UW16 CGENTRY CGIFFchar_get_gpos_pts(FSP UW16 index, UW16 num, UW16 *pts, SL32 *x, SL32 *y)
#else 
UW16 CGENTRY CGIFFchar_get_gpos_pts(index, num, pts, x, y)
UW16 index;
UW16 num;
UW16 *pts;
SL32 *x;
SL32 *y;
#endif
{
    UW16 error;
    PBUCKET pBkt;
    fs_GlyphInputType *ttInput;
    register fsg_SplineKey* key;
    fnt_ElementType *elementPtr;
    SB8* workSpacePtr;
    fsg_OffsetInfo* offsetPtr;
    SL32 *px,*py;
    SW16 *pe;
    SW16 nc,np;
    SW16 i,n;
    UW16 ssnum;

    ssnum = if_state.fcCur.ssnum;
    if_state.fcCur.ssnum = RAW_GLYPH;
    error = CGIFfont (FSA (PFONTCONTEXT)&if_state.fcCur);     
    if ((error = CGIFfont (FSA (PFONTCONTEXT)&if_state.fcCur)))
        return error;
    if ((error = map_and_set_scale(FSA (PFONTCONTEXT)&if_state.fcCur, index)))
        return error;
    pBkt = GET_pBUCKET(if_state.pbucket);
    ttInput = (fs_GlyphInputType *) MEMptr(pBkt->p.tt.buffInput);
    key = (fsg_SplineKey *)MEMptr(ttInput->memoryBases[KEY_PTR_BASE]);
    if (!key)
        return ERR_TT_NULL_KEY;
    /* potentially do delayed pre program execution */
    if ( key->executePrePgm ) {
        key->executePrePgm = false;
        if ( (error = fsg_RunPreProgram( FSA key )) != 0 )
            return error;
    }
    key->GetSfntGlyphPtr = ttInput->GetSfntGlyphPtr;
    key->RelSfntGlyphPtr = ttInput->RelSfntGlyphPtr;
    key->glyphLength = 0;       /* initialized*/
    if ( (error = fsg_GridFit( FSA key, /*useHints*/1)) != 0 )
        return error;
    elementPtr = &(key->elementInfoRec.interpreterElements[GLYPHELEMENT]);
    workSpacePtr = (SB8*)key->memoryBases[WORK_SPACE_BASE];
    offsetPtr = &(key->elementInfoRec.offsets[GLYPHELEMENT]);
    px = (SL32 *)(workSpacePtr + offsetPtr->newXOffset);
    py = (SL32 *)(workSpacePtr + offsetPtr->newYOffset);
    pe = (SW16 *)(workSpacePtr + offsetPtr->endPointOffset);
    nc = elementPtr->nc;
    np = nc ? 1+pe[nc-1] : 0;

    for (i=0; i<num; i++)
    {
        n = pts[i];
        if (n >= np)
            return error;
        x[i] = px[n];
        y[i] = py[n];
    }
    if_state.fcCur.ssnum = ssnum;     
    if ((error = CGIFfont (FSA (PFONTCONTEXT)&if_state.fcCur)))
        return error;
    return NO_ERR;
} /* CGIFFchar_get_gpos_pts */

#endif    /* TT_RDR */

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值