T168_111\appl\Text\Agfa:第51~56

fc_syntl.h    //

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/FCO/FC_SYNTL.H_V   1.27   Aug 22 2003 09:03:02   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/FCO/FC_SYNTL.H_V  $ 
 * 
 *    Rev 1.27   Aug 22 2003 09:03:02   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.26   Aug 01 2003 10:23:46   Joe
 * Added FCO_PREALLOCATE support.
 * 
 *    Rev 1.25   Jun 20 2003 13:56:14   Galejs
 * get rid of 4 unused fields in skelNode
 * 
 *    Rev 1.24   Sep 20 2002 19:12:40   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.23   May 09 2001 18:04:42   Galejs
 * data-type cleanup
 * 
 *    Rev 1.22   Feb 03 2000 10:52:08   galejs
 * get rid of dangerous "long" dcls (AGAIN)
 * 
 *    Rev 1.21   02 Oct 1998 08:34:02   JOE
 * "rstackH" changes (by tbh).
 * 
 *    Rev 1.20   10 Sep 1998 17:30:28   GALEJS
 * remove C++-style comment
 * 
 *    Rev 1.19   24 Aug 1998 16:19:18   JOE
 * Changed "MM2" to "FCO2".
 * 
 *    Rev 1.18   21 Jul 1998 13:36:16   JOE
 * More MicroType 2 changes (by tbh).
 * 
 *    Rev 1.16   20 Mar 1998 11:31:58   GALEJS
 * 64-bit port
 * 
 *    Rev 1.15   11 May 1995 16:06:34   MIKE
 * Changed INFLATE.italicAngle int -> long; Added INFLATE.origItalAngle.
 * 
 *    Rev 1.14   07 Apr 1995 08:41:12   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.13   08 Feb 1995 17:20:04   MIKE
 * Changed pointers to MEM_HANDLE & offsets in MODEL, INFLATE.
 * 
 *    Rev 1.12   31 Jan 1995 10:50:20   MIKE
 * Added Y and XDimProjType to INFLATE structure
 * 
 *    Rev 1.11   13 Jan 1995 19:05:30   MIKE
 * Removed "numYdimens", "numXdimens" from INFLATE structure
 * 
 *    Rev 1.10   01 Dec 1994 11:22:52   MIKE
 * Change "FCWstandYstem" to "FCWstanYstem", etc.
 * 
 *    Rev 1.9   29 Nov 1994 10:25:28   MIKE
 * Added FCO-wide stem/width/height to INFLATE structure.
 * 
 *    Rev 1.8   27 Oct 1994 15:25:50   MIKE
 * Changed INFLATE.yClassDefLo(Hi) from uchar* to ushort.
 * 
 *    Rev 1.7   14 Sep 1994 14:06:22   MIKE
 * Split INFLATE.numYXconstdim and INFLATE.YXconstDims array.
 * 
 *    Rev 1.6   11 Sep 1994 10:21:46   MIKE
 * Changes to INFLATE structure: split X & Y dimensions; added numYXstanStem.
 * 
 *    Rev 1.5   09 Sep 1994 14:13:08   MIKE
 * Changed INFLATE and MODELTYPE structures for standard dims (FCO v.6)
 * 
 *    Rev 1.4   29 Jul 1994 14:31:36   MIKE
 * Added 'MAX_ANCHOR_PTS'
 * 
 *    Rev 1.3   22 Apr 1994 14:07:04   LISA
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.2   31 Mar 1994 17:55:24   MIKE
 * Add italicSwitch to MODELTYPE; added italicAngle to INFLATE.
 * 
 *    Rev 1.1   16 Mar 1994 11:41:16   MIKE
 * Reordered arrays in INFLATE structure for better comprehension.
 * 
 *    Rev 1.0   11 Mar 1994 09:45:22   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 09:03:02  $ */

/* fc_syntl.h */


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

/* History
 *
 * 16-Mar-94  mby  Reorderd arrays in INFLATE structure to correspond to
 *                 FCO file structure - makes fc_da.c easier to understand.
 * 31-Mar-94  mby  Added italicSwitch to MODELTYPE. Added italicAngle to INFLATE.
 * 29-Jul-94  mby  Added 'MAX_ANCHOR_PTS'
 * 06-Sep-94  tbh  INFLATE structure: Changed standard stems from single element to list of elements
 *                 and added flag to indicate: no standard dim proc; standard proc; or stanstan proc.
 * 07-Sep-94  mby  Added 'chgrpIndex' to MODELTYPE.
 * 09-Sep-94  mby  Dimension overflow!
 *                 Split 'numYXdimens' into 'numYdimens' & 'numXdimens'.
 *                 Split arrays 'YXdimensions', 'YXdimType', and 'YXRTZflags'
 * 10-Sep-94  mby  Added INFLATE.numYXstanStem
 * 14-Sep-94  mby  Split INFLATE.YXconstDims array; INFLATE.numYXconstdim.
 * 27-Oct-94  mby  Changed INFLATE.yClassDefLo, yClassDefHi from char*
 *                 to ushort. These are offsets into the Y Class Table.
 * 29-Nov-94  mby  Added FCWstand[Y/X][stem/HT/WD] to INFLATE structure
 *                 for FCO-wide metric.
 * 01-Dec-94  mby  Change INFLATE.FCWstandYstem to "FCWstanYstem", etc.
 * 13-Jan-95  mby  Removed "numYdimens", "numXdimens" from INFLATE structure.
 * 27-Jan-95  tbh  Added Y and XDimProjType to INFLATE structure.
 * 08-Feb-95  mby  In MODEL, INFLATE structures changed pointers to MEM_HANDLE
 *                 and offsets. Moved 'XdimProjType' FCTYPE structure.
 * 10-May-95  mby  Italic Aspect Ratio: changed INFLATE.italicAngle type from
 *                 int to long. Added INFLATE.origItalicAngle.
 * 10-Mar-98  slg  Don't use "long" dcls (incorrect if 64-bit platform)
 * 15-Jul-98  tbh  typedef's for MODEL data for MM2
 * 24-Aug-98  jfd  Changed all references of MM2 to FCO2.
 * 01-Oct-98  tbh  rstackH
 * 03-Feb-00  slg  Don't use "long" dcls (incorrect if 64-bit platform)
 * 30-Jul-03  jfd  Added FCO_PREALLOCATE support.
 */
 
#ifndef __FC_SYNTL__
#define __FC_SYNTL__

#define  NUM_YX_SKEL      0xff
#define  NUM_Y_TREES      0xff
#define  NUM_YLINES       0xff
#define  NUM_YCLASS       0xff
#define  NUM_DIMENS       0xff
#define  NUM_LOOPS        0x40
#define  MAX_ANCHOR_PTS   4
#define  ABOVE_STAN       2  /* Standard dimension cut-in limit has not been reached */
#define  AT_STAN          1  /* Standard dimension cut-in limit has been reached */
#define  BELOW_STAN       0  /* Standard-standard dimension cut-in limit has been reached */

/*
The following data description supports an individual character model */

#if FCO2
typedef struct
  {
  MEM_HANDLE     xCORdataH;
  MEM_HANDLE     yCORdataH;
  MEM_HANDLE     yxEXTdataH;
  MEM_HANDLE     xCORsubstH;
  MEM_HANDLE     yCORsubstH;
  MEM_HANDLE     yxEXTsubstH;
  MEM_HANDLE     modelDataH;   /* Handle to MODEL data arrays      */
#if FCO_PREALLOCATE
  SL32  modelDataSize;
#endif
  MEM_HANDLE     rstackH;      /* Handle to MODEL processing stack */
  UB8  *forest[2];
  UB8  *YXcSegSource;
  UB8  *loopEnd;
  UB8  *potDiscard;
  UB8  Ebit;         /* bit position for beginning of YXcSegSource data */
  UB8  Pbit;         /* bit position for beginning of potDiscard data  */
  UB8  chgrpIndex;   /* FCO wide character group index for stan dims */
  UB8  numLoops;     /* Number of loops this model */
  UB8  numYXcSegs;   /* Number of contour segments in this character description */
  UB8  localCompressSwitch;   /* Indicates whether we use local compression (1) or not (0) */
  SL32           italicSwitch; /* Indicates whether character is italic: 0 no, 1 yes */

  SW16          loopEndOff;   /* List of indices to last segment end point in each loop */
  } MODELTYPE;


typedef struct skelNodeLabel     /* definition for each node in skeletal tree */
  {
  UB8         coordIndex;
  UB8         rTypology;
  UB8         gridAlign;
  UB8         assocSign;
  UB8         dimStat;
  UB8         assocValue;
  UB8         dm_indx;
  UB8         yClassIndex;
  UB8         CORorEXT;
  UB8         localbits;
  UB8         localbase;
  struct skelNodeLabel  *parent;
  struct skelNodeLabel  *child;
  struct skelNodeLabel  *sibling;
  }      skelNode;


#else
typedef struct
  {
  UB8  chgrpIndex;   /* FCO wide character group index for stan dims */
  UB8  numLoops;     /* Number of loops this model */
  UB8  italicSwitch; /* Indicates whether character is italic: 0 no, 1 yes */
  UB8  numYroot;     /* Number of Yskeletal trees (numXroot is assumed to be 1) */
  UB8  numYXskel;    /* Number of Y and X skeletal tree nodes  (including interps) */
  UB8  numYXcSegs;   /* Number of contour segments in this character description */
  UB8  numYXcSegSo;  /* Number of contour segment source specifiers in theis character description */
  UB8  numYXdim;     /* Total number of dimension indices used by this character (Y then X) */
  UB8  numLocYXdims; /* Number of local segment end point descriptions for Y and X */
  MEM_HANDLE     modelDataH;   /* Handle to MODEL data arrays */
#if FCO_PREALLOCATE
  SL32  modelDataSize;
#endif
  SW16          skelListOff;  /* List of Y then X skeletal points in tree processing order */
  SW16          dimIndexOff;  /* List of indices to the Dimension Stack located in Typeface Global Data Area */
  SW16          yclAssIndxOff;/* List of indices to either the yclass or the yline stacks in the Typeface Global Data Area */
  SW16          loopEndOff;   /* List of indices to last segment end point in each loop */
  SW16          numAssocOff;  /* List of number of associations (children) branching from this Y or X skeletal node */
  SW16          alignAttribOff; /* List of grid alignment attributes: 0 = do not align;  1 = do align */
  SW16          assocValueOff;/* List of Standard Association Class Values: 00=NULL; 01=STEM; 10=WDHT; 11=LFSB/RTSB */
  SW16          rTypeYXOff;   /* List of indicators for computing rTypes: YPROC: 0=YL; 1=YC; XPROC: 0=LS; 1=AJ; */
  SW16          dimStatOff;   /* List of dim status for assoc coming into each Y or X skel node (except root): 0 = no dim; 1 = dim */
  SW16          assocSignOff; /* List of signs of the assoc coming into each Y or X skeletal node: 0 = positive; 1 = negative */
  SW16          cSegSourcYXOff; /* List of indicators as to source of data for computing a given contour seg end point */
  } MODELTYPE;
#endif

/*
The following data description supports the Global Data applied to a group of characters (i.e., entire typeface or all lowercase, etc.) */

typedef struct      /* Typeface global data */
  {
  UL32  standardYheight;  /* Standard height for this character group */
  UL32  standardXwidth;   /* Standard width for this character group */
  SL32          italicAngle;      /* Italic angle adjusted for aspect ratio */
  SL32           origItalicAngle;  /* Italic angle of the typeface: 2**15 x tangent */
  UL32  numYline;         /* Number of ylines this character group */
  UL32  numYclass;        /* Number of yclasses */
  UL32  numYconstdim;     /* Number of Y constrained dimensions */
  UL32  numXconstdim;     /* Number of X constrained dimensions */
  UL32  FCWstanYstem;     /* FCO wide standard Y stem */
  UL32  FCWstanXstem;     /* FCO wide standard X stem */
  UL32  FCWstanYwidth;    /* FCO wide standard height */
  UL32  FCWstanXwidth;    /* FCO wide standard width  */
  UL32  stanStanYstem;    /* Standard-standard Y dimension */
  UL32  stanStanXstem;    /* Standard-standard X dimension */
  UL32  stanFlag;         /* flag to indicate state of processing re: standard dimensions */
  UL32  numYXstanStem;    /* Number of Y and X standard stems */
  MEM_HANDLE    globalDataH;      /* Handle to TF global data */
  SW16         standardYstemOff; /* List of Standard Y stem weight for this char group */
  SW16         standardXstemOff; /* List of Standard X stem weight for this char group */
  SW16         yLineValueOff;    /* List of yline values at 127th EM: max = 2X EM */
  SW16         YdimensionsOff;   /* List of Y dimension values as 127th of stan ht/wd (max = 2X) or 63rd of stan stem (max = 4X) */
  SW16         XdimensionsOff;   /* List of X dimension values as 127th of stan ht/wd (max = 2X) or 63rd of stan stem (max = 4X) */
  SW16         YconstDimsOff;    /* List of Y dimensions (by index) that are constrained */
  SW16         XconstDimsOff;    /* List of X dimensions (by index) that are constrained */
  SW16         YdimTypeOff;      /* List of Y dim type bits (0 & 1 are relevant): */
               /*   00 = character group STEM   01 = character group HT/WD */
               /*   10 = FCO-wide STEM          11 = FCO-wide HT/WD        */
  SW16         XdimTypeOff;      /* List of X dim type bits: same as for Y */
  SW16         YRTZflagsOff;     /* List of Y round-to-zero flags: 0=NO RTZ; 1=RTZ */
  SW16         XRTZflagsOff;     /* List of X round-to-zero flags: 0=NO RTZ; 1=RTZ */
/* next two values are offsets into yClassData Table */
  UW16 yClassDefLo;     /* List of indices to yLineValue list for low yline of this yclass */
  UW16 yClassDefHi;     /* List of indices to yLineValue list for high yline of this yclass */
  } INFLATE;  /* SUBGLOBAL; */

#endif    /* __FC_SYNTL__ */
 

fcntl.h   /

空文件

fcodump2.txt    、、、、、、、、、、、、、、、、、、、、、、、、、

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/RTS/FCO/FCODUMP2.C_V   1.8   Aug 22 2003 09:03:02   LynchR  $ */
/* $Log:   I:/BULL/URIP/RTS/FCO/FCODUMP2.C_V  $ 
 * 
 *    Rev 1.8   Aug 22 2003 09:03:02   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.7   Jul 21 2003 17:34:56   Galejs
 * UFST_debug_on() replaces trace_sw=1
 * 
 *    Rev 1.6   Jun 23 2003 14:01:04   Galejs
 * ufstport.h
 * 
 *    Rev 1.5   29 Jul 1999 17:21:02   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.4   03 Sep 1998 16:57:30   MAC
 * Added FCO_CURVE_DATA condition.
 * 
 *    Rev 1.3   24 Aug 1998 16:21:52   JOE
 * Changed "MM2" to "FCO2".
 * 
 *    Rev 1.2   29 Jul 1998 19:20:52   MAC
 * Update for MM2 and convergent font fix
 * 
 *    Rev 1.1   07 Jul 1998 22:04:10   MAC
 * Fixed warning messages.
 * 
 *    Rev 1.0   06 Jul 1998 17:13:04   GALEJS
 * Initial revision.
 * 
 */
/* $Date:   Aug 22 2003 09:03:02  $ */

/* FCODUMP.C */


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

/* History
 *
 * 08-Dec-97  mby  Current version ==> PVCS archive.
 * 06-Jul-98  slg  Modify to work with reentrant UFST code - "UFST_ON" option
 *                    won't work anymore - replaced by "FCO_STANDALONE" =
 *                    below-the-line flag in cgconfig.h
 *
 *                   Archived as new file = /rts/fco/fcodump2.c, so that a copy
 *                    of this utility is captured as part of each snapshot.
 * 07-Jul-98  mac  Fixed warning messages.
 * 24-Aug-98  jfd  Changed all references of MM2 to FCO2.
 * 28-Jul-99  ks   Changed DEBUG compiler directive to AGFADEBUG. 
 */

/******************************************************/
/*****  PLEASE READ THIS  ****  PLEASE READ THIS  *****/
/******************************************************/

/* You must build this program with the files FC_DA.C and
 * FC_DAFIL.C; and FC_INTF2.C for FCO2 == 1.
 *
 * The flag "FCO_STANDALONE" in cgconfig.h must be set to 1.
 * The FCO_CURVE_DATA_RELEASE could be set to 0 to dump compressed and
 * uncompressed fcos.
 *
 * In your makefile, you must include the /RTS/FCO, /RTS/INC, and /SYS/INC
 *    directories in your include-file searchpath 
 */


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

#include "cgconfig.h"
#include "ufstport.h"
#include "shareinc.h"
#include "fc_dakey.h"

/* 2 error codes copied from now-obsolete fcconfig.h */
#define  ERR_fco_CharIndOffset        540
#define  ERR_fco_CharPosition         541

#define PI  3.14159265358979323846264338327950288419716939937510582097494459230781
#define E   2.71828182845904523536028747135266249775724709369995957496696762772407

#if defined (LINT_ARGS)
static UW16 FCtableOffset( TABLETYPE*, int, long* );
static UW16 FCchmapNew   ( CHMAPTYPE*, int, FCTYPE* );
static VOID FCchmapClose ( CHMAPTYPE* );
int print_special( int argc, char** argv, FCTYPE* );

#else   /* !LINT_ARGS */
static UW16 FCtableOffset();
static UW16 FCchmapNew   ();
static VOID FCchmapClose ();
int print_special();
#endif /* !LINT_ARGS */


static void print_help( void )
{
    printf("\nUsage:  FCODUMP <fco-file> [ -td ]\n");
}


/*===================== TABLETYPE =================================*/

/*--------------------*/
/*   FCtableOffset    */
/*--------------------*/
/*  Return offset within the table for a given tableIndex */
/*  Mirror of FCtableOffset static function in FC_DA.C */

#if defined (ANSI_DEFS)
static UW16 FCtableOffset( TABLETYPE* table, int tableIndex, long *offset )
#else
static UW16 FCtableOffset( table, tableIndex, offset )
TABLETYPE* table;
int tableIndex;
long *offset;
#endif
{
    if (tableIndex<0 || tableIndex >= table->numEntries)
        return (UW16)ERR_fco_TableOffset;
    if (!DAsetPos(table->f, table->tableStart + 4L*(long)tableIndex))
        return (UW16)ERR_fco_TableOffset;
    *offset = DAgetLong(table->f);
    *offset += table->start;
    return DAerror(table->f) ? (UW16)ERR_fco_TableOffset : (UW16)SUCCESS;
}


/*=========================== Charmap =====================================*/

/* ------------------------------ FCchmapNew ------------------------------
 *
 * Mirror of FCchmapNew static function in FC_DA.C
 *
 * Description: Opens new CHMAPTYPE object. Loads FCO charmap data into memory.
 * Parameters:  chmap - CHMAPTYPE object
 *              mapIndex - charmap index number assigned to this FCO typeface
 *              fc -     Font Collection object
 * Returns:     SUCCESS  or
 *                ERR_fco_ChmapNew_CorruptData, ERR_fco_ChmapNew_Memory
 * Called by:   FCfontNew()
 */
#if defined (ANSI_DEFS)
static UW16 FCchmapNew( CHMAPTYPE* chmap, int mapIndex, FCTYPE* fc )
#else
static UW16 FCchmapNew( chmap, mapIndex, fc )
CHMAPTYPE* chmap;
int mapIndex;
FCTYPE* fc;
#endif
{
    DAFILE* f = fc->f;
    int     entrySz;
    unsigned int  numSimpleChars, numAccentCC, numComplexCC, numParts;
    unsigned int  numAccExc;
    long offset, saveOffset;
    unsigned short* buffer;
    unsigned char*  p;
    unsigned short *mt0, *mt1, *mt1a, *mt2, *mtuc ;
    UW16     status=0;

    chmap->mapTablesH = NIL_MH;

    if (FCtableOffset(&fc->charMaps, mapIndex, &offset) != SUCCESS)
    {
        status = ERR_fco_ChmapNew_CorruptData;
        goto error;
    }
    if (!DAsetPos(f, offset))
    {
        status = ERR_fco_ChmapNew_CorruptData;
        goto error;
    }

    { int i; p = (unsigned char*)chmap->pclt;   /* PCLT array */
      for(i=0; i<8; i++)
        *p++ = DAgetChar(f);
    }

/* Compute buffer size required to hold data and allocate memory. */
   {
    long bufSize;
    if (!chmap->chmapFormatPS)
        entrySz = 4;    /* Size of charset element */
    else
        entrySz = 6;
    saveOffset = offset + 8;
    offset = saveOffset;
    DAsetPos(f, offset);
    numSimpleChars = DAgetInt(f);
    offset += (2 + (numSimpleChars * entrySz));
    DAsetPos(f, offset);
    numAccentCC = DAgetInt(f);
    offset += (2 + (numAccentCC * entrySz));
    DAsetPos(f, offset);
    numAccExc = DAgetInt(f);    /* Version A */
    offset += (2 + (numAccExc<<2));
    DAsetPos(f, offset);
    numComplexCC = DAgetInt(f);
    offset += (2 + ((numComplexCC+1) * entrySz));
    DAsetPos(f, offset);
    numParts = DAgetInt(f);
    if (DAerror(f))
    {
        status = ERR_fco_ChmapNew_CorruptData;
        goto error;
    }

/* load simpChars + accentCCs + complexCCs + unicodeParts */
    entrySz >>= 1;
    bufSize = (((numSimpleChars + numAccentCC + numComplexCC + 1) * entrySz)
                + numParts
                + (numAccExc<<1)
              ) * sizeof(short);
    if ((chmap->mapTablesH = BUFalloc((SL32)bufSize)) == NIL_MH)
    {
        status = ERR_fco_ChmapNew_Memory;
        goto error;
    }
   }

/* Assign CHMAPTYPE pointers to memory just allocated. */
    chmap->mapTabAccOff = numSimpleChars * entrySz;
    chmap->mapTabAccExcOff = chmap->mapTabAccOff + numAccentCC * entrySz;
    chmap->mapTabCplxOff = chmap->mapTabAccExcOff + (numAccExc << 1);
    chmap->mapTabUniOff = chmap->mapTabCplxOff + ((numComplexCC+1) * entrySz);
    mt0  = (unsigned short*)MEMptr(chmap->mapTablesH);
    mt1  = mt0 + chmap->mapTabAccOff;
    mt1a = mt0 + chmap->mapTabAccExcOff;
    mt2  = mt0 + chmap->mapTabCplxOff;
    mtuc = mt0 + chmap->mapTabUniOff;
    chmap->numSimpleChars = numSimpleChars;
    chmap->numAccentCC    = numAccentCC;
    chmap->numComplexCC   = numComplexCC;
    chmap->numParts       = numParts;
    chmap->numAccentExcs  = numAccExc;

    offset = saveOffset;
    DAsetPos(f, offset);

    /* char map table for simple chars */
    DAgetInt(f);  /* skip over two bytes */
    buffer = mt0;
    numSimpleChars *= entrySz;
    while(numSimpleChars--)
        *buffer++ = DAgetUWord(f);

    /* char map table for short form compounds */
    DAgetInt(f);  /* skip over two bytes */
    buffer = mt1;
    numAccentCC *= entrySz;
    while(numAccentCC--)
        *buffer++ = DAgetUWord(f);

    /* char map table for short form Accent Exceptions */
    DAgetInt(f);  /* skip over two bytes */
    buffer = mt1a;
    numAccExc <<= 1;
    while(numAccExc--)
        *buffer++ = DAgetUWord(f);

    /* char map table for long form compounds */
   {
    unsigned int ii = (numComplexCC + 1) * entrySz;
    DAgetInt(f);  /* skip over two bytes */
    buffer = mt2;
    while(ii--)
        *buffer++ = DAgetUWord(f);
   }

    /* char map table of unicodes for long form compound pieces */
    DAgetInt(f);  /* skip over two bytes */
    buffer = mtuc;
    while(numParts--)
        *buffer++ = DAgetUWord(f);
    if (DAerror(f))
    {
        status = ERR_fco_ChmapNew_CorruptData;
        goto error;
    }

    return (UW16)SUCCESS;

error:
    FCchmapClose(chmap);
    return status;
}
/*** FCchmapNew ***/


/* ----------------------------- FCchmapClose -----------------------------
 *
 * Mirror of FCchmapClose static function in FC_DA.C
 *
 * Description: Closes CHMAPTYPE object
 * Parameters:  chmap - CHMAPTYPE object
 * Called by:   FCfontClose(), FCchmapNew [error]
 */
#if defined (ANSI_DEFS)
static VOID FCchmapClose( CHMAPTYPE* chmap )
#else
static VOID FCchmapClose( chmap )
CHMAPTYPE* chmap;
#endif
{
    BUFfree(chmap->mapTablesH);
    chmap->mapTablesH = NIL_MH;
}

/* --------------------------------------------------------------------- */
/* ------------------------------ m a i n ------------------------------ */
/* --------------------------------------------------------------------- */
int    main( int argc, char **argv )
{
    FCTYPE fc;
    int ii;
    unsigned short *mt0, *mt1, *mt1a, *mt2, *mtuc ;
    unsigned char* TFglobalData;
    UW16     status=0;
    FONTTYPE fcoFont;

    if (argc < 2)
    {
        print_help();
        exit(1);
    }

    printf("FCODUMP  %s\n", argv[1]);
    printf("For FCO Format Version 1.2, 1.3 & 1.4 (source code is now part of UFST)\n");
    printf("\n");

#ifdef AGFADEBUG
    UFST_debug_on(FSA0);    /* enable DBG:DBG8 debug printout */
#endif

    if ((status = FCnew( &fc, argv[1])) != SUCCESS)
    {
        printf("FCnew() failed! Error %d\n", status);
        exit(1);
    }

    printf("Version:   0x%X\n", fc.version);
    printf("Length:    %ld\n", fc.len);
    printf("numTables: %d\n", fc.numTables);
    if (!DAsetPos(fc.f, 7L))
    {
        status = ERR_fco_FCnew_CorruptData;
        goto error1;
    }
    for (ii=0; ii<fc.numTables; ii++)
    {
        unsigned int key = (unsigned)DAgetChar(fc.f);
        long offset = DAgetLong(fc.f);
        printf("  %2d %7ld (0x%lx)\n", key, offset, offset);
    }
    if (fc.version != VERSION_NUMBER && fc.version != VERSION_12)
    {
        printf("\nIncorrect FCO Version %x\n", fc.version);
        status = ERR_fco_versionError;
        goto error1;
    }

    if (argc > 2)
    {
        print_special(argc, argv, &fc);
        FCclose(&fc);
        exit(0);
    }

    printf("\n");
    printf("FCO-wide dimensions:\n");
    printf("  Standard X Stem:   %d\n", fc.FCWstanXstem);
    printf("  Standard Y Stem:   %d\n", fc.FCWstanYstem);
    printf("  Standard X Width:  %d\n", fc.FCWstanXwidth);
    printf("  Standard Y Height: %d\n\n", fc.FCWstanYwidth);
    printf("FCO max points:      %d\n\n", fc.maxPoints);

   {
    short* dimArray = (short*)MEMptr(fc.charGroupOffsH);
    int ii;
    printf("Dimension offsets by Character Group (%d Groups):\n", fc.numCharGroups);
    for (ii=0; ii < fc.numCharGroups*2; ii++)
    {
        if (ii == 0)  printf("  Y data: %d\n", dimArray[ii]);
        else if (ii == fc.numCharGroups)  printf("  X data: %d\n", dimArray[ii]);
        else
            printf("          %d\n", dimArray[ii]);
    }
   }

    printf("\n");
    if (fc.modelGroups.key == TOPOKEY)
    {
        int ii;
        printf("Model Library:\n");
        printf("  Length:       %ld\n", fc.modelGroups.len);
        printf("  numModelGrps: %d\n", fc.modelGroups.numEntries);
        printf("  offsets, chGrIx, numModels:\n");
        for (ii=0; ii<fc.modelGroups.numEntries; ii++)
        {
            long  mgOffset;
            int   chGrIx;
                int    NumModels;
            if (FCtableOffset(&(fc.modelGroups), ii, &mgOffset) != SUCCESS)
            {
                status = ERR_fco_ModelNew_CorruptData;
                goto error1;
            }
            DAsetPos(fc.f, mgOffset);
            chGrIx = DAgetChar(fc.f);
#if FCO2
            NumModels = DAgetChar(fc.f);
#else
            NumModels = DAgetInt(fc.f);
#endif
            printf("  %7ld  %3u  %d\n", mgOffset, chGrIx, NumModels);
        }
    }
    else
        printf("Model Library does not exist\n");

    printf("\n");
    if (fc.charMaps.key == CHARMAPKEY)
    {
        int ii;
        long  cmOffset;
        printf("Character Maps:\n");
        printf("  Length:       %ld\n", fc.charMaps.len);
        printf("  numCharMaps: %d\n", fc.charMaps.numEntries);
        printf("  offsets:\n");
        for (ii=0; ii<fc.charMaps.numEntries; ii++)
        {
            if (FCtableOffset(&(fc.charMaps), ii, &cmOffset) != SUCCESS)
            {
                status = ERR_fco_ChmapNew_CorruptData;
                goto error1;
            }
            printf("    %ld\n", cmOffset);
        }
        for (ii=0; ii<fc.charMaps.numEntries; ii++)
        {
            CHMAPTYPE chmap;
            unsigned int jj;
            int tableSize;
            chmap.chmapFormatPS = 1;
            if (fc.postStrings == NIL_MH)
                chmap.chmapFormatPS = 0;
            if ((status = FCchmapNew(&chmap, ii, &fc)) != SUCCESS)
                goto error1;
            tableSize = 2;
            if (chmap.chmapFormatPS) tableSize++;

            mt0  = (unsigned short*)MEMptr(chmap.mapTablesH);
            mt1  = mt0 + chmap.mapTabAccOff;
            mt1a = mt0 + chmap.mapTabAccExcOff;
            mt2  = mt0 + chmap.mapTabCplxOff;
            printf("  Character Map %d, numSimpleChars: %d\n", ii, chmap.numSimpleChars);
            printf("    Unicode   mgIndex          Unicode   mgIndex\n");
            for (jj=0; jj<chmap.numSimpleChars; jj++)
            {
                printf("    %04x      %4d", mt0[jj*tableSize], mt0[jj*tableSize+1]);
                if (jj & 1) printf("\n");
                else printf("         ");
            }
            if (jj & 1) printf("\n");

            printf("  Character Map %d, numAccentCC: %d\n", ii, chmap.numAccentCC);
            printf("    Unicode   ccIndex          Unicode   ccIndex\n");
            for (jj=0; jj<chmap.numAccentCC; jj++)
            {
                int index;
                index = mt1[jj*tableSize+1];
                printf("    %04x      %4d", mt1[jj*tableSize], index & 0x7FFF);
                if (index < 0)  printf("\035ALT");
                else            printf("    ");
                if (jj & 1) printf("\n");
                else printf("     ");
            }
            if (jj & 1) printf("\n");

            if (chmap.numAccentExcs)
            {
              printf("  Character Map %d, nrAccentExceptions: %d\n", ii, chmap.numAccentExcs);
              printf("    UC Base   UC Accent        UC Base UC   Accent\n");
              for (jj=0; jj<chmap.numAccentExcs; jj++)
              {
                  printf("    %04x      %04x", mt1a[jj*2], mt1a[jj*2+1]);
                  if (jj & 1) printf("\n");
                  else printf("         ");
              }
              if (jj & 1) printf("\n");
            }

            printf("  Character Map %d, numComplexCC: %d\n", ii, chmap.numComplexCC);
            printf("    Unicode   mirPartNum       Unicode   mirPartNum\n");
            for (jj=0; jj<chmap.numComplexCC; jj++)
            {
                printf("    %04x      %04x", mt2[jj*tableSize], mt2[jj*tableSize+1]);
                if (jj & 1) printf("\n");
                else printf("         ");
            }
            if (jj & 1) printf("\n");
            FCchmapClose(&chmap);
        }
    }       /* CHARMAPKEY */
    else
        printf("Character Maps do not exist\n");

    printf("\n");
    if (fc.compCharDefs.key == COMPOUNDKEY)
    {
        int ii;
        printf("Compound Characters:\n");
        printf("  Length:       %ld\n", fc.compCharDefs.len);
        printf("  numCompChars: %d\n", fc.compCharDefs.numEntries);
        if (!DAsetPos(fc.f, fc.compCharDefs.tableStart))
        {
            printf("\nUnable to locate Compound Character Table\n");
            status = ERR_fco_FCnew;
            goto error1;
        }
        printf("  unicodeBase unicodeAccent         unicodeBase unicodeAccent\n");
        for (ii=0; ii<fc.compCharDefs.numEntries; ii++)
        {
            int n1, n2;
            n1 = DAgetInt(fc.f);
            n2 = DAgetInt(fc.f);
            printf("  %04x        %04x", n1, n2);
            if ((ii+1)%2 != 0)
                printf("                ");
            else
                printf("\n");
        }
        if (ii%2 != 0)
            printf("\n");
    }
    else
        printf("Compound Character Table does not exist\n");

    printf("\n");
    if (fc.fonts.key == TFTABLEKEY)
    {
        int ii, ny, nx;
        int numFonts = FCnumFonts(&fc);
        printf("Typeface Table:\n");
        printf("  Length:       %ld\n", fc.fonts.len);
        printf("  numFonts: %d\n", numFonts);
        printf("  offsets:\n");
        for (ii=0; ii<numFonts; ii++)
        {
            long  tfOffset;
            if ((FCtableOffset(&(fc.fonts), ii, &tfOffset)) != SUCCESS)
            {
                status = ERR_fco_FInfo_CorruptData;
                goto error1;
            }
            printf("    %ld\n", tfOffset);
        }
        for (ii=0; ii<numFonts; ii++)
        {
            int jj;
            int tableSize;
            char* pStrings;
            long charOffset;

            if ((status = FCfontNew( &fcoFont, &fc, ii, PRIMARYFLAG)) != SUCCESS)
            {
                printf("\nFCfontNew failed! Index %d\n", ii);
                goto error2;
            }
            pStrings = (char*)FCgetStringsPtr(&fc);
            if (fcoFont.cvfFlag != 2 && fcoFont.cvfFlag != 3)
            {
                TFglobalData = (unsigned char*)MEMptr(fcoFont.inflate.globalDataH);
                tableSize = 2;
                if (fcoFont.chmap.chmapFormatPS) tableSize++;
            }

            if (fcoFont.cvfFlag != 2 && fcoFont.cvfFlag != 3)
                printf("  \nTypeface %d\n", ii);
            else
                printf("  \nTypeface %d   This is an algorithmically narrowed face\n", ii);
            printf("    len          = %ld\n", fcoFont.len);
            printf("    startOff     = %ld (0x%lX)\n", fcoFont.startOff,fcoFont.startOff);
            printf("    TF Global sz = %d\n", fcoFont.offsetDescrip - fcoFont.headerSize);
            printf("    charMapIndex = %u\n", fcoFont.charMapIndex);
            if (fcoFont.cvfFlag != 2 && fcoFont.cvfFlag != 3)
            {
                printf("    PCLT Typeface       = %ld \"%s\"\n", fcoFont.tfDesc.pcltFontNumber, pStrings + fcoFont.tfDesc.pcltTypeface);
                printf("    Typeface Name       = %s\n", pStrings + fcoFont.tfDesc.tfName);
                printf("    Family Name         = %s\n", pStrings + fcoFont.tfDesc.familyName);
                printf("    Design units per em = %u\n", fcoFont.tfDesc.scaleFactor);
                printf("    Spaceband width = %u\n", fcoFont.tfDesc.spaceBand);
                printf("    pluginDescr  = %04x\n", fcoFont.tfDesc.pluginDescriptor);
            }
            printf("    Outline sharing: %u\n", fcoFont.segShareFont);
            if (fcoFont.cvfFlag)
            {
                unsigned short* prI = (unsigned short*)(MEMptr(fcoFont.cvf.cvHorAdjListH) + fcoFont.cvf.cvProhItalOff);
                unsigned short* hAdj = (unsigned short*)MEMptr(fcoFont.cvf.cvHorAdjListH);
                printf("    Convergent Font Data:\n");
                printf("        Alternate Font Index  %d\n", fcoFont.cvf.fIndex);
                printf("        Italic Angle Tangent  %d (%.2lf?\n", fcoFont.cvf.italTan,
                       atan((double)fcoFont.cvf.italTan/32768.0)*180.0/PI);
                if (fcoFont.cvfFlag == 2) {
                    printf("        Narrowing Parameter   %u (%.2lf\\%)\n", fcoFont.cvf.narrowFactor,
                           (double)fcoFont.cvf.narrowFactor / 327.68);
                }
                printf("        italicProhibit Table  %d entries\n", fcoFont.cvf.numProhItal);
                for (jj=0; jj<fcoFont.cvf.numProhItal; jj++)
                    printf("                              0x%04x\n", prI[jj]);
                printf("        Global Horizontal Adj %d\n", fcoFont.cvf.globalHorAdj);
                printf("        Horizontal Adj Table  %d entries\n", fcoFont.cvf.numHorAdj);
                for (jj=0; jj<fcoFont.cvf.numHorAdj; jj++)
                    printf("                              0x%04x %d\n", hAdj[jj*2], hAdj[jj*2+1]);
            }

            if (fcoFont.cvfFlag == 2 || fcoFont.cvfFlag == 3)
                continue;    /* algorithmic narrowing */

            printf("\n");
            printf("    stdYheight    = %u\n", fcoFont.inflate.standardYheight);
            printf("    stdXwidth     = %u\n", fcoFont.inflate.standardXwidth);
            printf("    italicAngle   = %d, (%.2lf deg)\n", fcoFont.inflate.origItalicAngle,
               atan((double)fcoFont.inflate.origItalicAngle/32768.0)*180.0/PI);

            printf("    orThreshold   = %u\n", fcoFont.tfDesc.orThreshold);
            printf("    standardCutin = %u\n", fcoFont.tfDesc.standardCutin);
            printf("    stanStanCutin = %u\n", fcoFont.tfDesc.stanStanCutin);
            printf("    stanStanYstem = %u    stanStanXstem = %u\n", fcoFont.inflate.stanStanYstem, fcoFont.inflate.stanStanXstem);
            printf("    standardYstems  standardXstems     numYXstanStem = %d\n", fcoFont.inflate.numYXstanStem);

           {
            unsigned int *standYstem, *standXstem; unsigned int jj;
            standYstem = (unsigned int*)(TFglobalData + fcoFont.inflate.standardYstemOff);
            standXstem = (unsigned int*)(TFglobalData + fcoFont.inflate.standardXstemOff);
            for (jj=0; jj<fcoFont.inflate.numYXstanStem; jj++)
                printf("       %4u     %u\n", standYstem[jj], standXstem[jj]);
            if (jj%16)
                printf("\n");
           }

           {
            unsigned char* yLineValue; unsigned int jj;
            yLineValue = TFglobalData + fcoFont.inflate.yLineValueOff;
            printf("    numYline     = %d\n", fcoFont.inflate.numYline);
            for (jj=0; jj<fcoFont.inflate.numYline; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", yLineValue[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
           }

            ny = fc.numYdimens;
            nx = fc.numXdimens;

           {
            unsigned char *Ydimensions, *Xdimensions;
            Ydimensions = TFglobalData + fcoFont.inflate.YdimensionsOff;
            Xdimensions = TFglobalData + fcoFont.inflate.XdimensionsOff;
            printf("    numYdimens  = %d       numXdimens  = %d\n", ny, nx);
            printf("    Ydimensions:\n");
            for (jj=0; jj<ny; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", Ydimensions[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
            printf("    Xdimensions:\n");
            for (jj=0; jj<nx; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", Xdimensions[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
           }

           {
            unsigned char *YdimType, *XdimType;
            YdimType = TFglobalData + fcoFont.inflate.YdimTypeOff;
            XdimType = TFglobalData + fcoFont.inflate.XdimTypeOff;
            printf("    YdimType:\n");
            for (jj=0; jj<ny; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", YdimType[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
            printf("    XdimType:\n");
            for (jj=0; jj<nx; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", XdimType[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
           }

           {
            unsigned char *YRTZflags, *XRTZflags;
            YRTZflags = TFglobalData + fcoFont.inflate.YRTZflagsOff;
            XRTZflags = TFglobalData + fcoFont.inflate.XRTZflagsOff;
            printf("    YRTZflags:\n");
            for (jj=0; jj<ny; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", YRTZflags[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
            printf("    XRTZflags:\n");
            for (jj=0; jj<nx; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", XRTZflags[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
           }

           {
            unsigned char *YconstDims, *XconstDims;
            YconstDims = TFglobalData + fcoFont.inflate.YconstDimsOff;
            XconstDims = TFglobalData + fcoFont.inflate.XconstDimsOff;
            printf("    numYconstdim= %d\n", fcoFont.inflate.numYconstdim);
            for (jj=0; jj<ny; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", YconstDims[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
            printf("    numXconstdim= %d\n", fcoFont.inflate.numXconstdim);
            for (jj=0; jj<nx; jj++)
            {
                if (jj%16 == 0)  printf("      ");
                printf("%u ", XconstDims[jj]);
                if ((jj+1)%16 == 0)
                printf("\n");
            }
            if (jj%16)
                printf("\n");
           }
           {
                unsigned int jj;
    /* Print simple character info; Character Set Exceptions */
            mt0  = (unsigned short*)MEMptr(fcoFont.chmap.mapTablesH);
            mt2  = mt0 + fcoFont.chmap.mapTabCplxOff;
            mtuc = mt0 + fcoFont.chmap.mapTabUniOff;
            printf("\n    %d Characters, %d Exceptions, charIndOffset = %ld:\n",
                    fcoFont.chmap.numSimpleChars, fcoFont.numExceptions, fcoFont.charIndOffset);
            printf("      Unicode, MdlGrpIdx, Length, Position, Escapement, ModelIndex");
            if (fcoFont.segShareFont != 0xFFFF)
                printf(", OutlineSharing");
            printf("\n");
            printf("      ============================================================");
            if (fcoFont.segShareFont != 0xFFFF)
                printf("================");
            printf("\n");

            charOffset = 0;
            if (!DAsetPos(fcoFont.f, fcoFont.charIndOffset))
            {
                status = ERR_fco_CharIndOffset;
                goto error2;
            }
            for (jj=0; jj < (fcoFont.chmap.numSimpleChars+fcoFont.numExceptions); jj++)
            {
                long charPos;
                unsigned int chEsc, chEscSh;
                unsigned int chMod;
                int len;
                long save;
                len = (unsigned char)DAgetChar(fcoFont.f);
                save = DAgetPos(fcoFont.f);
                if(len == 255)
                {
                    long sizeoff;
                    sizeoff = charOffset + fcoFont.charIndOffset + fcoFont.numExceptions +
                                fcoFont.chmap.numSimpleChars;
                    DAsetPos(fcoFont.f, sizeoff);
                    len = DAgetInt(fcoFont.f);
                    charOffset += 2;
                }
                charPos = charOffset +
                          fcoFont.charIndOffset + fcoFont.numExceptions +
                          fcoFont.chmap.numSimpleChars;
                charOffset += len;
                if (!DAsetPos(fcoFont.f, charPos))
                {
                    status = ERR_fco_CharPosition;
                    goto error2;
                }
                chEsc = DAgetUWord(fcoFont.f);
                chEscSh = chEsc & SEGSHAR_MASK;
                chEsc &= SEGSHAR_EMASK;
                if (jj < fcoFont.chmap.numSimpleChars)
                   printf("      %04x     %-9d %4d     %-8ld %5u",
                           mt0[2*jj], mt0[2*jj+1], len, charPos, chEsc);
                else
                {
                   unsigned short* excTbl = (unsigned short*)MEMptr(fcoFont.excTbl_CCinfoH);
                   int offset = tableSize*(jj - fcoFont.chmap.numSimpleChars);
                   printf("      %04x     %-9d %4d     %-8ld %5u",
                           excTbl[offset], excTbl[offset+1], len, charPos, chEsc);
                }
                if (chEscSh == 0xC000)
                   printf(" A\n");
                else
                {
                   chMod = (unsigned int)DAgetChar(fcoFont.f);
                   printf("        %d", chMod);
                   if (fcoFont.segShareFont != 0xFFFF)
                      printf("           %c%c",
                              (chEscSh & 0x8000) ? '1' : '0',
                              (chEscSh & 0x4000) ? '1' : '0'  );
                   printf("\n");
                }
                DAsetPos(fcoFont.f, save);
            }   /* for(jj ... */
              }

            if (fcoFont.numExceptions)
            {
                unsigned short* excTbl;
                printf("Typeface Charset Exception Table\n");
                printf("  Unicode, MdlGroupIx, PSstringOff\n");
                excTbl = (unsigned short*)MEMptr(fcoFont.excTbl_CCinfoH);
                for (jj=0; jj<fcoFont.numExceptions; jj++)
                {
                    int offset;
                    offset = tableSize*jj;
                    printf("%5d) %04x %4d", jj, excTbl[offset], excTbl[offset+1]);
                    if (fcoFont.chmap.chmapFormatPS)
                        printf(" %4d\n", excTbl[offset+2]);
                    else
                        printf("\n");
                }
            }

           if (fcoFont.chmap.numComplexCC)
           {
            unsigned short *excTbl, *escapeCC, *XYoffsCC; unsigned int jj;
            printf("Compound Characters (Font Dependent)\n");
            printf("  Unicode; Escapement; nrParts; Mirror; Unicodes & Offsets\n");
            excTbl = (unsigned short*)MEMptr(fcoFont.excTbl_CCinfoH);
            escapeCC = excTbl + fcoFont.cplxCCEsc;
            XYoffsCC = excTbl + fcoFont.cplxCCXYoff;
            for (jj=0; jj<fcoFont.chmap.numComplexCC; jj++)
            {
                int kk, offset, firstPart, nrParts, mirror;
                int esc;
                unsigned short unicode;
                offset = tableSize*jj;
                unicode = mt2[offset];
                firstPart = mt2[offset+1] & COMPLXFLAGSMASK;
                mirror = (unsigned int)mt2[offset+1] >> COMPLXFLAGSSHIFT;
                nrParts = (mt2[offset+tableSize+1] & COMPLXFLAGSMASK) - firstPart;
                esc = escapeCC[jj] & SEGSHAR_EMASK;
                printf("%5d) %04x %5d ", jj, unicode, esc);
                if ((escapeCC[jj] & SEGSHAR_MASK) != SEGSHAR_MASK)
                {
                  printf("%d mir=%d   ", nrParts, mirror);
                  for (kk=0; kk<nrParts; kk++)  {
                      printf("u=%04x %d %d   ", mtuc[firstPart+kk],
                             XYoffsCC[(firstPart+kk)<<1],
                             XYoffsCC[((firstPart+kk)<<1)+1]);
                  }
                  printf("\n");
                }
                else
                  printf("A\n");
            }
           }
           else
                printf("No Complex Compound Characters\n");

            FCfontClose(&fcoFont);
        }   /* for (ii=0; ii<numFonts; ii++)  */
    }   /* TFTABLEKEY */
    else
        printf("Typeface Table does not exist\n");

    FCclose(&fc);
    return SUCCESS;


error2:
    FCfontClose(&fcoFont);
    goto error1;
error1:
    printf("error %d!\n", status);
    FCclose(&fc);
    exit(1);

    return SUCCESS;
}

int print_special( int argc, char** argv, FCTYPE* fc )
{
    UW16 status=0;
    if (argc >= 3)
    {
        char s[64];
        sscanf(argv[2], "%s", s);
        if (strcmp(s, "-td") != 0)
            return FAILURE;
    }
    if (fc->fonts.key == TFTABLEKEY)
    {
        int ii;
        unsigned char* str1;
        FONTTYPE fcoFont;
        int numFonts = FCnumFonts(fc);
        for (ii=0; ii<numFonts; ii++)
        {
            char* pStrings;
            if ((status = FCfontNew( &fcoFont, fc, ii, PRIMARYFLAG)) != SUCCESS)
            {
                FCfontClose(&fcoFont);
                printf("\nFCfontNew failed! Index %d. Error %d\n", ii, status);
                exit(1);
            }
            pStrings = (char*)FCgetStringsPtr(fc);
            printf("\nFCO Index %3d\n-------------\n", ii);
            printf("    Design units per em = %u\n", fcoFont.tfDesc.scaleFactor);
            printf("    Spaceband width     = %u\n", fcoFont.tfDesc.spaceBand);
            printf("    Thin Space width    = %u\n", fcoFont.tfDesc.fixedSpaceThin);
            printf("    EN Space width      = %u\n", fcoFont.tfDesc.fixedSpaceEN);
            printf("    EM Space width      = %u\n", fcoFont.tfDesc.fixedSpaceEM);
            printf("    Baseline position   = %d\n", fcoFont.tfDesc.baselinePosition);
            printf("    Ascender            = %d\n", fcoFont.tfDesc.ascender);
            printf("    Descender           = %d\n", fcoFont.tfDesc.descender);
            printf("    Font Xmin           = %d\n", fcoFont.tfDesc.FontBBoxXmin);
            printf("    Font Xmax           = %d\n", fcoFont.tfDesc.FontBBoxXmax);
            printf("    Cap Height          = %d\n", fcoFont.tfDesc.capHeight);
            printf("    x Height            = %d\n", fcoFont.tfDesc.xHeight);
            printf("    Fixed Pitch         = %s\n", (fcoFont.tfDesc.isFixedPitch ? "TRUE" : "FALSE"));
            printf("    italicAngle         = %d, (%.2lf deg)\n", fcoFont.tfDesc.italicAngle,
               atan((double)fcoFont.tfDesc.italicAngle/32768.0)*180.0/PI);
            printf("    Underscore depth    = %d\n", fcoFont.tfDesc.uScoreDepth);
            printf("    Undersc'r thickness = %d\n", fcoFont.tfDesc.uScoreThickness);
            printf("    PCLT font number    = %ld\n", fcoFont.tfDesc.pcltFontNumber);
            printf("    PCLT style          = 0x%04x\n", fcoFont.tfDesc.pcltStyle);
            printf("    PCLT CharComplement = 0x");
            { int jj;
              for (jj=0; jj<8; jj++) {
                printf("%02x", fcoFont.tfDesc.pcltChComp[jj]);
              }
              printf("\n");
            }
            printf("    PCLT type family    = %d\n", fcoFont.tfDesc.pcltTypeFamily);
            printf("    PCLT typeface name  = \"%s\"\n", pStrings + fcoFont.tfDesc.pcltTypeface);
            printf("    PCLT file name      = \"%s\"\n", pStrings + fcoFont.tfDesc.pcltFileName);
            printf("    PCLT stroke weight  = %d\n", fcoFont.tfDesc.pcltStrokeWt);
            printf("    PCLT width type     = %d\n", fcoFont.tfDesc.pcltWidthType);
            printf("    PCLT serif style    = 0x%02x\n", fcoFont.tfDesc.pcltSerifStyle);
            printf("    us weight class     = %d\n", fcoFont.tfDesc.usWeightClass);
            printf("    us width class      = %d\n", fcoFont.tfDesc.usWidthClass);
            printf("    sFamilyClass        = %d\n", fcoFont.tfDesc.sFamilyClass);
            printf("    fsSelection         = %u, 0x%04x\n", fcoFont.tfDesc.fsSelection, fcoFont.tfDesc.fsSelection);
            str1 = fcoFont.tfDesc.panose;
            printf("    panose[10]          = %u %u %u %u %u %u %u %u %u %u\n",
               str1[0], str1[1], str1[2], str1[3], str1[4],
               str1[5], str1[6], str1[7], str1[8], str1[9] );
            printf("    orThreshold         = %u\n", fcoFont.tfDesc.orThreshold);
            printf("    Standard cut-in     = %u\n", fcoFont.tfDesc.standardCutin);
            printf("    StanStan cut-in     = %u\n", fcoFont.tfDesc.stanStanCutin);
            printf("    Plugin descriptor   = 0x%04x\n", fcoFont.tfDesc.pluginDescriptor);
            printf("    Typeface Name       = \"%s\"\n", pStrings + fcoFont.tfDesc.tfName);
            printf("    Family Name         = \"%s\"\n", pStrings + fcoFont.tfDesc.familyName);
            printf("    Weight Name         = \"%s\"\n", pStrings + fcoFont.tfDesc.weightName);
            printf("    Copyright notice    = \"%s\"\n", pStrings + fcoFont.tfDesc.copyrightNotice);
            printf("\n");

            FCfontClose(&fcoFont);
        }
    }
    return SUCCESS;
}

fill.c   、、、、、、、、、、、、、、、、、、、、、、///

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

/* $Header:   I:/BULL/URIP/RTS/BMP/FILL.C_V   1.38   Aug 21 2003 16:47:44   Galejs  $ */
/* $Log:   I:/BULL/URIP/RTS/BMP/FILL.C_V  $ 
 * 
 *    Rev 1.38   Aug 21 2003 16:47:44   Galejs
 * update copyright notice
 * 
 *    Rev 1.37   Jun 23 2003 14:03:52   Galejs
 * ufstport.h
 * 
 *    Rev 1.36   Jul 06 2001 15:32:06   Al
 * If NATORDER use faster fill even on chunks larger than 8
 * 
 *    Rev 1.35   Jul 06 2001 11:56:24   Galejs
 * allow 64-bit chunk to compile (although it still won't run...)
 * 
 *    Rev 1.34   Jun 14 2001 15:01:48   Al
 * Fast fill - added tran list to nzw buf
 * 
 *    Rev 1.33   May 03 2001 19:09:34   Galejs
 * data-type cleanup
 * 
 *    Rev 1.32   Aug 10 1999 15:12:08   galejs
 * include-file changes
 * 
 *    Rev 1.31   15 Jun 1998 17:08:54   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.30   24 Mar 1998 14:45:12   GALEJS
 * include-file changes
 * 
 *    Rev 1.29   04 Sep 1997 13:39:24   JOE
 * Removed all references to BJG_BOLD_P6 (by keb).
 * 
 *    Rev 1.28   05 Aug 1997 11:43:04   JOE
 * Modified for smear left problem (by keb).
 * 
 *    Rev 1.26   25 Jul 1997 09:15:08   AL
 * Corrected typo in BJG_BOLD_P6
 * 
 *    Rev 1.25   16 Jul 1997 11:46:44   JOE
 * Get rid of unreferenced local variables (by Jimmy).
 * 
 *    Rev 1.24   15 Jul 1997 16:03:08   JOE
 * Emboldening changes (by Karen).
 * 
 *    Rev 1.23   15 Jul 1997 10:16:20   AL
 * fix for PCL6 bold for rotation per BJG
 * 
 *    Rev 1.22   16 Jun 1997 14:22:26   AL
 * Can have GRAYSCALING without CGBITMAP
 * 
 *    Rev 1.21   04 Apr 1997 10:28:10   JOE
 * In smearnonorthogonal(), calling fp2word() to convert 2 FPNUM variables
 * to word values before comparing them.
 * 
 *    Rev 1.20   07 Mar 1997 18:51:46   MIKE
 * Fix compile errors: #define PERFASM 0; if_state_or_on -> if_state.or_on
 * 
 *    Rev 1.19   06 Feb 1997 16:30:42   PVCSADMN
 * Joe Kolb changed some logic in smearnorthogonal to use floating.
 * 
 *    Rev 1.18   24 Oct 1996 11:38:34   BJG
 * Revisions to enable char_size emboldening for PCL 6 emulation.
 * 
 *    Rev 1.17   23 Oct 1996 14:10:56   BJG
 * Revised changes made to PCL 6 emulation for emboldening.
 * 
 *    Rev 1.16   23 Oct 1996 12:02:34   BJG
 * Added emboldening for PCL 6 emulation.
 * 
 *    Rev 1.15   04 Dec 1995 13:01:48   MERRILL
 * cast to int. line 272
 * 
 *    Rev 1.14   06 Apr 1995 15:08:22   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.13   22 Apr 1994 09:20:42   LISA
 * Modified copyright/disclaimer notice.
 * 
 *    Rev 1.12   09 Feb 1994 13:28:46   JOE
 * Changed cgfill() arg types for args 3 and 4 from SW16 to int to 
 * match !ANSI_DEFS version.
 * 
 *    Rev 1.11   02 Sep 1993 13:24:48   JOE
 * In THIRTYTWO_BIT_CHUNK version of get_bytes() macro, added missing ";"
 * before closing "}".
 * 
 *    Rev 1.10   27 Jul 1993 12:31:42   AL
 * Non-zero winding changes
 * 
 *    Rev 1.8   14 May 1993 16:02:00   JOE
 * Rewrote byte_position() function so as too work on SPARC.
 * Fixed fill_bold() so as to work on SPARC.
 * 
 *    Rev 1.7   14 Apr 1993 08:45:24   JOE
 * Added ANSI_DEFS declaration for function byte_position().
 * 
 *    Rev 1.6   13 Apr 1993 09:13:02   JOE
 * Added external declaration for "bit[]" table because it has been moved 
 * from BITMAP.H .
 * 
 *    Rev 1.5   12 Apr 1993 10:45:34   JOE
 * In fill() and fill_bold(), fixed compiler errors when attempting to
 * autoincrement a pointer variable which is being cast to a different
 * type.
 * 
 *    Rev 1.4   07 Apr 1993 12:02:46   JOE
 * Added raster line organization support.
 * 
 *    Rev 1.3   12 Feb 1993 11:11:52   JOE
 * VXWorks support.
 * 
 *    Rev 1.2   05 Jan 1993 16:03:28   JOE
 * ANSI C function declaration changes.
 * 
 *    Rev 1.1   14 Dec 1992 09:28:16   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   10 Dec 1992 08:33:10   LISA
 * Initial revision.
*/
/* $Date:   Aug 21 2003 16:47:44  $ */
/* fill.c */
/*
 *
 *
 * HISTORY:
 *
 *  27-Nov-90  bg   Changed type of "or_on" in EXTERN statement from
 *                  WORD to BOOLEAN to resolve some missing pixel
 *                  problems.
 *  30-Jan-91 dET   added funtion prototyping for MSC
 *  31-Jan-91 dET   Modify for MSC multi-model compilation. Change (BYTE)1-...
 *                  to (UBYTE)1-...
 *  10-Feb-91 awr   Moved making_bold and or_on to SCALE structure.
 *  17-Apr-91 awr   Conditionally compiled fill_bold()
 *  17-Jun-91 jfd   Moved "debug.h" after "port.h".
 *   1-Sep-91 awr   Included "bitmap.h"
 *  12-Oct-91 awr   Missing pixel recovery and pseudo bold are no 
 *                  longer mutually exclusive.
 *  24-Feb-92 jfd   Added include for <stdio.h>.
 *  03-Apr-92 rs    Portability cleanup (see port.h).
 *  15-Nov-92 rs    Port to Macintosh - rename fill() to cgfill().
 *  05-Jan-93 jfd   ANSI C function declaration changes.
 *  08-Feb-93 jfd   VXWorks support.
 *  07-Apr-93 jfd   Added support for raster line organizations.
 *  12-Apr-93 jfd   In fill() and fill_bold(), fixed compiler errors when
 *                  attempting to autoincrement a pointer variable which
 *                  is being cast to a different type.
 *  13-Apr-93 jfd   Added external declaration for "bit[]" table because it
 *                  has been removed from BITMAP.H.
 *  14-Apr-93 jfd   Added ANSI_DEFS declaration for function byte_position().
 *  13-May-93 jfd   Rewrote byte_position() function so as to work on
 *                  non-INTEL platforms.
 *                  Fixed fill_bold() so as to work on non-INTEL platforms.
 *  30-Jun-93 awr   Created more efficient nzw fill.
 *  02-Sep-93 jfd   In THIRTYTWO_BIT_CHUNK version of get_bytes() definition,
 *                  added missing ";" before closing "}".
 *  07-Feb-94 jfd   Changed cgfill() arg types for args 3 and 4 from SW16
 *                  to int to match !ANSI_DEFS version.
 *  23-Oct-96 dbk   Added LINT_ARGS support to new functions. Modified
 *                  declaration for FPNUM zero.
 *************************
 *  19-Oct-93 JLB   Added "PERFASM" to use an asm version of cgfill().
 *  19-Sep-96 jlb   if_state.or_on -> if_state_or_on for isram.
 *  06-Dec-96 JPK   Added performance changed to smearorthogonal.
 *  01-Jan-97 JPK   Changed some logic in smearnonorthogonal to use floating
 *                  point and rounding later.                                
 ************************
 *  07-Mar-97 mby   Fix compile errors: #define PERFASM 0
 *                  if_state_or_on -> if_state.or_on
 *  04-Apr-97 jfd   In smearnonorthogonal(), calling fp2word() to convert
 *                  2 FPNUM variables to word values before comparing them.
 *  16-Jun-97 awr   Conditionally compiled entire module on CGBITMAP.
 *  16-Jul-97 keb   Modified isbetween()for emboldening in the 4th quadrant
 *  16-Jul-97 keb   Modified cgsmear()so that memory was freed ONLY if it was allocated 
 *  28-Jul-97 keb   Modified to support different chunk sizes 
 *  05-Aug-97 keb   Modified for smear left problem
 *  03-Sep-97 keb   Removed references to BJG_BOLD_P6
 */

#include "cgconfig.h"

#if CGBITMAP            /* Conditionally compile entire module */

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

#define PERFASM 0     /* Change to "1" to use asm code */

#include <stdio.h>
//#if PERFASM
//#include "perfasm.gh"      /* JLB */
//#endif

#include "ufstport.h"
#include "dbg_ufst.h"

#include "shareinc.h"

#include "filltab.h"     /* definition of fill tables */


#if RASTER_ORG == SIXTEEN_BIT_CHUNK
#define get_bytes(b, c)  {b[0]=(UB8)(c&0xFF); b[1]=(UB8)(c>>8);}
#define put_bytes(b, c)  c = (((CHUNK)b[1])<<8) + ((CHUNK)b[0])

#elif RASTER_ORG == THIRTYTWO_BIT_CHUNK
#define get_bytes(b, c)  {b[0]=(UB8)(c&0xFF); c>>=8; \
                          b[1]=(UB8)(c&0xFF); c>>=8; \
                          b[2]=(UB8)(c&0xFF); b[3]=(UB8)(c>>8);}
#define put_bytes(b, c)  c = (((CHUNK)b[3] )<<24) + (((CHUNK)b[2] )<<16) + \
                             (((CHUNK)b[1] )<< 8) + ((CHUNK)b[0])

#elif RASTER_ORG == SIXTYFOUR_BIT_CHUNK
#define get_bytes(b, c)  { }
#define put_bytes(b, c)  { }
#endif

#if LEFT_TO_RIGHT_BIT_ORDER
#define set_first_byte(p,b)   p=&(b[CHUNK_COUNT-1])
#define next_byte(p)          p--
#else
#define set_first_byte(p,b)   p=b
#define next_byte(p)          p++
#endif

#if !PERFASM  /* JPK */

/*--------------------*/
/*    fill            */
/*--------------------*/
#if defined (ANSI_DEFS)
GLOBAL VOID
cgfill (FSP LPUB8 srcptr, LPUB8 dstptr, SL32 width, SL32 depth,
        LPUB8 or_buffer)
#else
GLOBAL VOID
cgfill (srcptr, dstptr, width, depth, or_buffer)
    LPUB8  srcptr;
    LPUB8  dstptr;
    SL32    width;   /* width of bitmap in bytes   */
    SL32    depth;   /* depth of bitmap in rasters */
    LPUB8  or_buffer;
#endif
{
    UB8  p;

    SB8   mode;          /* writing beam mode.  Off = 0,  on = 1. */
    SL32    iw,id;

    DBG("cgfill()\n");


#if NATORDER
    {
        for (id=0; id<depth; id++)    /* for each horizontal raster       */
        {
            mode = 0;                   /* beam off at start of each raster */
            for(iw=0; iw < width; iw++) /* loop for each "chunk" of the raster */
            {
                p = *srcptr++;  /* grab next byte */
                if(mode == 0)
                {
                    mode      = off_nxt[p];
                    *dstptr++ = off_tab[p];
                }
                else
                {
                    mode      = (UB8)1 - off_nxt[p];
                    *dstptr++ = ~off_tab[p];
                }
            }
        }
    }
#else   /* not NATORDER  */
    {
        LPCHUNK chunkdstptr;
        LPCHUNK chunksrcptr;
        SL32 bct, num_chunks;
        CHUNK   chunk;
        UB8  b[CHUNK_COUNT];
        LPUB8 pb;

        /* Convert pointers to CHUNK-specific pointer variables */

        chunkdstptr = (LPCHUNK)dstptr;
        chunksrcptr = (LPCHUNK)srcptr;

        num_chunks = width >> (CHUNK_SHIFT - 3);
        for (id=0; id<depth; id++)    /* for each horizontal raster       */
        {
            mode = 0;                   /* beam off at start of each raster */
            for(iw=0; iw < num_chunks; iw++)
            {
             /* Grab next byte of chunk */

                chunk = *chunksrcptr++;  /* grab chunk of bytes */
                get_bytes(b, chunk);
                set_first_byte(pb, b);
                for(bct=0; bct<CHUNK_COUNT; bct++)
                {
                    p = *pb;
                    if(mode ==0)
                    {
                        mode = off_nxt[p];
                        *pb  = off_tab[p];
                    }
                    else
                    {
                        mode = (UB8)1 - off_nxt[p];
                        *pb  = ~off_tab[p];
                    }
                    next_byte(pb);
                }
                put_bytes(b, chunk);
                *chunkdstptr++ = chunk;
            }
        }
    }
#endif  /* (RASTER_ORG != EIGHT_BIT_CHUNK) */
}
#endif /* PERFASM */

#endif /* CGBITMAP */
 

filltab.h     /

/* 
 * Copyright (C) 2003 Agfa Monotype Corporation. All rights reserved.
 */
/* $Header:   I:/BULL/URIP/SYS/INC/FILLTAB.H_V   1.9   Aug 22 2003 09:43:52   LynchR  $ */
/* $Log:   I:/BULL/URIP/SYS/INC/FILLTAB.H_V  $ 
 * 
 *    Rev 1.9   Aug 22 2003 09:43:52   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.8   Sep 23 2002 14:27:32   Galejs
 * test for multiple includes (part of bug # 76)
 * 
 *    Rev 1.7   11 Jan 1999 19:54:12   GALEJS
 * use CONST keyword for read-only data
 * 
 *    Rev 1.6   18 Dec 1997 16:37:18   GALEJS
 * delete if-0 code
 * 
 *    Rev 1.5   07 Apr 1995 11:31:18   LISA
 * Changed copyright information from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.4   22 Apr 1994 15:31:28   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.3   07 Apr 1993 10:58:04   JOE
 * Added raster line organization support.
 * 
 *    Rev 1.2   14 Jan 1993 11:06:12   LISA
 * Removed CntrlZ character
 * 
 *    Rev 1.1   14 Dec 1992 08:46:34   LISA
 * Made change to Log keyword
 * 
 *    Rev 1.0   09 Dec 1992 11:38:14   LISA
 * Initial revision.
*/
/* $Date:   Aug 22 2003 09:43:52  $ */
/************************************************************************
**    filltab.h                                                        **
**    -------------------------------------------------------------    **
 *
 *
*************************************************************************
    Product:   Intellifont Sub-System    
    Component: Tables used by the fill module    
    Author:    Al Ristow    
*************************************************************************/
/* History                                                          */
/*   filltab.h    29-Nov-85                                         */
/*                 4-Oct-89  removed last two complimentary tables  */
/*                                                                  */
/*                02-Apr-92  Portability cleanup (see port.h).      */
/*                                                                  */
/*                05-Apr-93  Added suppport for right-to-left bit   */
/*                           ordering of "chunk"s for off_nxt[] and */
/*                           off_tab[] tables (jfd).                */
/*                                                                  */
/*  These tables are used by the "fill" module to generate bit maps */
/*  from transition arrays.                                         */
/*                                                                  */
/*  These tables were generated (in crude form) by the program      */
/*  "b.c" and then edited to their current exquisite form.          */
/*                                                                  */
/********************************************************************/

#ifndef __FILLTAB__
#define __FILLTAB__

#if LEFT_TO_RIGHT_BIT_ORDER

CONST UB8 off_tab[256] =

            { 0x00, 0x01, 0x03, 0x02, 0x07, 0x06, 0x04, 0x05, 
              0x0F, 0x0E, 0x0C, 0x0D, 0x08, 0x09, 0x0B, 0x0A, 
              0x1F, 0x1E, 0x1C, 0x1D, 0x18, 0x19, 0x1B, 0x1A, 
              0x10, 0x11, 0x13, 0x12, 0x17, 0x16, 0x14, 0x15, 
              0x3F, 0x3E, 0x3C, 0x3D, 0x38, 0x39, 0x3B, 0x3A, 
              0x30, 0x31, 0x33, 0x32, 0x37, 0x36, 0x34, 0x35, 
              0x20, 0x21, 0x23, 0x22, 0x27, 0x26, 0x24, 0x25, 
              0x2F, 0x2E, 0x2C, 0x2D, 0x28, 0x29, 0x2B, 0x2A, 
              0x7F, 0x7E, 0x7C, 0x7D, 0x78, 0x79, 0x7B, 0x7A, 
              0x70, 0x71, 0x73, 0x72, 0x77, 0x76, 0x74, 0x75, 
              0x60, 0x61, 0x63, 0x62, 0x67, 0x66, 0x64, 0x65, 
              0x6F, 0x6E, 0x6C, 0x6D, 0x68, 0x69, 0x6B, 0x6A, 
              0x40, 0x41, 0x43, 0x42, 0x47, 0x46, 0x44, 0x45, 
              0x4F, 0x4E, 0x4C, 0x4D, 0x48, 0x49, 0x4B, 0x4A, 
              0x5F, 0x5E, 0x5C, 0x5D, 0x58, 0x59, 0x5B, 0x5A, 
              0x50, 0x51, 0x53, 0x52, 0x57, 0x56, 0x54, 0x55, 
              0xFF, 0xFE, 0xFC, 0xFD, 0xF8, 0xF9, 0xFB, 0xFA, 
              0xF0, 0xF1, 0xF3, 0xF2, 0xF7, 0xF6, 0xF4, 0xF5, 
              0xE0, 0xE1, 0xE3, 0xE2, 0xE7, 0xE6, 0xE4, 0xE5, 
              0xEF, 0xEE, 0xEC, 0xED, 0xE8, 0xE9, 0xEB, 0xEA, 
              0xC0, 0xC1, 0xC3, 0xC2, 0xC7, 0xC6, 0xC4, 0xC5, 
              0xCF, 0xCE, 0xCC, 0xCD, 0xC8, 0xC9, 0xCB, 0xCA, 
              0xDF, 0xDE, 0xDC, 0xDD, 0xD8, 0xD9, 0xDB, 0xDA, 
              0xD0, 0xD1, 0xD3, 0xD2, 0xD7, 0xD6, 0xD4, 0xD5, 
              0x80, 0x81, 0x83, 0x82, 0x87, 0x86, 0x84, 0x85, 
              0x8F, 0x8E, 0x8C, 0x8D, 0x88, 0x89, 0x8B, 0x8A, 
              0x9F, 0x9E, 0x9C, 0x9D, 0x98, 0x99, 0x9B, 0x9A, 
              0x90, 0x91, 0x93, 0x92, 0x97, 0x96, 0x94, 0x95, 
              0xBF, 0xBE, 0xBC, 0xBD, 0xB8, 0xB9, 0xBB, 0xBA, 
              0xB0, 0xB1, 0xB3, 0xB2, 0xB7, 0xB6, 0xB4, 0xB5, 
              0xA0, 0xA1, 0xA3, 0xA2, 0xA7, 0xA6, 0xA4, 0xA5, 
              0xAF, 0xAE, 0xAC, 0xAD, 0xA8, 0xA9, 0xAB, 0xAA };


CONST UB8 off_nxt[256] = 

            { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };

#else

CONST UB8 off_tab[256] =

            { 0x00, 0xFF, 0xFE, 0x01, 0xFC, 0x03, 0x02, 0xFD,
              0xF8, 0x07, 0x06, 0xF9, 0x04, 0xFB, 0xFA, 0x05,
              0xF0, 0x0F, 0x0E, 0xF1, 0x0C, 0xF3, 0xF2, 0x0D,
              0x08, 0xF7, 0xF6, 0x09, 0xF4, 0x0B, 0x0A, 0xF5,
              0xE0, 0x1F, 0x1E, 0xE1, 0x1C, 0xE3, 0xE2, 0x1D,
              0x18, 0xE7, 0xE6, 0x19, 0xE4, 0x1B, 0x1A, 0xE5,
              0x10, 0xEF, 0xEE, 0x11, 0xEC, 0x13, 0x12, 0xED,
              0xE8, 0x17, 0x16, 0xE9, 0x14, 0xEB, 0xEA, 0x15,
              0xC0, 0x3F, 0x3E, 0xC1, 0x3C, 0xC3, 0xC2, 0x3D,
              0x38, 0xC7, 0xC6, 0x39, 0xC4, 0x3B, 0x3A, 0xC5,
              0x30, 0xCF, 0xCE, 0x31, 0xCC, 0x33, 0x32, 0xCD,
              0xC8, 0x37, 0x36, 0xC9, 0x34, 0xCB, 0xCA, 0x35,
              0x20, 0xDF, 0xDE, 0x21, 0xDC, 0x23, 0x22, 0xDD,
              0xD8, 0x27, 0x26, 0xD9, 0x24, 0xDB, 0xDA, 0x25,
              0xD0, 0x2F, 0x2E, 0xD1, 0x2C, 0xD3, 0xD2, 0x2D,
              0x28, 0xD7, 0xD6, 0x29, 0xD4, 0x2B, 0x2A, 0xD5,
              0x80, 0x7F, 0x7E, 0x81, 0x7C, 0x83, 0x82, 0x7D,
              0x78, 0x87, 0x86, 0x79, 0x84, 0x7B, 0x7A, 0x85,
              0x70, 0x8F, 0x8E, 0x71, 0x8C, 0x73, 0x72, 0x8D,
              0x88, 0x77, 0x76, 0x89, 0x74, 0x8B, 0x8A, 0x75,
              0x60, 0x9F, 0x9E, 0x61, 0x9C, 0x63, 0x62, 0x9D,
              0x98, 0x67, 0x66, 0x99, 0x64, 0x9B, 0x9A, 0x65,
              0x90, 0x6F, 0x6E, 0x91, 0x6C, 0x93, 0x92, 0x6D,
              0x68, 0x97, 0x96, 0x69, 0x94, 0x6B, 0x6A, 0x95,
              0x40, 0xBF, 0xBE, 0x41, 0xBC, 0x43, 0x42, 0xBD,
              0xB8, 0x47, 0x46, 0xB9, 0x44, 0xBB, 0xBA, 0x45,
              0xB0, 0x4F, 0x4E, 0xB1, 0x4C, 0xB3, 0xB2, 0x4D,
              0x48, 0xB7, 0xB6, 0x49, 0xB4, 0x4B, 0x4A, 0xB5,
              0xA0, 0x5F, 0x5E, 0xA1, 0x5C, 0xA3, 0xA2, 0x5D,
              0x58, 0xA7, 0xA6, 0x59, 0xA4, 0x5B, 0x5A, 0xA5,
              0x50, 0xAF, 0xAE, 0x51, 0xAC, 0x53, 0x52, 0xAD,
              0xA8, 0x57, 0x56, 0xA9, 0x54, 0xAB, 0xAA, 0x55 };


CONST UB8 off_nxt[256] = 


            { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
              0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };

#endif

#endif    /* __FILLTAB__ */
 

fm.c     

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

/* $Header:   I:/BULL/URIP/RTS/DA/FM.C_V   1.84   Dec 14 2004 14:17:46   galejss  $ */
/* $Log:   I:/BULL/URIP/RTS/DA/FM.C_V  $
 * 
 *    Rev 1.84   Dec 14 2004 14:17:46   galejss
 * make all DBG calls 16-bit-compatible
 * 
 *    Rev 1.83   Oct 25 2004 18:26:38   galejss
 * rd_char() changes (clean up IF disk/rom logic; some simplification)
 * 
 *    Rev 1.82   Aug 10 2004 16:41:40   galejss
 * changes for runtime no-symset-mapping option
 * 
 *    Rev 1.81   Jul 16 2004 17:19:12   galejss
 * changes for IF Disk/ROM
 * 
 *    Rev 1.80   Aug 22 2003 08:53:38   LynchR
 * Updated copyright notice.
 * 
 *    Rev 1.79   Aug 21 2003 13:58:30   IndrelR
 * Added feature for processing XL bitmaps.
 * 
 *    Rev 1.78   Aug 01 2003 19:07:10   Galejs
 * fix compiler warnings in ifget_FontBBox
 * 
 *    Rev 1.77   Jul 22 2003 13:48:58   Galejs
 * reentrancy / debug fixes
 * 
 *    Rev 1.76   Jun 19 2003 18:46:34   Galejs
 * get rid of NON_IF_FONT; clean up compiler issues & debug
 * 
 *    Rev 1.75   Nov 26 2002 17:47:32   Galejs
 * add casts to all MEMptr() references (to fix compiler warnings)
 * 
 *    Rev 1.74   Sep 30 2002 12:21:34   Galejs
 * 32-bit charcode support (for rjl)
 * 
 *    Rev 1.73   Mar 28 2002 14:34:28   Joe
 * Format 11 changes:
 * 1.) In DArd_char(), if unbound pcleo, call
 * SYMmap() instead of MSL_to_CG_index()
 * for cg number.
 * 
 *    Rev 1.72   31 Aug 2001 16:09:40   Zhang
 * Alpha changes (by dz ).
 * 
 *    Rev 1.0   31 Aug 2001 16:09:40   Zhang
 * Initial revision.
 * 
 *    Rev 1.71   27 Aug 2001 16:13:46   JOE
 * 
 * In DArd_char(), removed conditional compile surrounding setting
 * of "tmp_fc.ExtndFlags" to 0. This was causing an access violation
 * if processing an HQ2 character from a pcleo with ASIAN_ENCODING off.
 * 
 *    Rev 1.70   24 Aug 2001 14:08:44   JOE
 * 
 * Added function MSL_to_CG_index().
 * In DArd_char(), call MSL_to_CG_index() to extract CG # prior to
 * lookup in HQ3 table. (by jfd)
 * DISK / ROM changes (by jwd).
 * 
 *    Rev 1.69   Jul 19 2001 18:36:18   Galejs
 * more 64-bit changes
 * 
 *    Rev 1.68   Jun 28 2001 18:30:04   Galejs
 * add NAT_ALIGN==8 cases for 64-bit Intellifont support
 * 
 *    Rev 1.67   May 03 2001 19:58:42   Galejs
 * data-type cleanup
 * 
 *    Rev 1.66   Mar 24 2000 17:33:12   galejs
 * DISK_FONTS tests need to be IF_DISK
 * 
 *    Rev 1.65   17 Mar 2000 11:53:12   JOE
 * Fixed comment (by ks).
 * 
 *    Rev 1.63   Jan 28 2000 15:56:10   galejs
 * test for DISK_FONTS rather than !ROM
 * 
 *    Rev 1.62   Aug 16 1999 13:10:26   galejs
 * include-file changes; USING_16_BIT_DOS test
 * 
 *    Rev 1.61   29 Jul 1999 17:20:48   JOE
 * Changed DEBUG directive to AGFADEBUG (by ks).
 * 
 *    Rev 1.60   16 Feb 1999 13:25:14   JOE
 * Added 'v' intellifont file format support to FMprocess_face() (by ks).
 * 
 *    Rev 1.59   21 Jan 1999 17:11:32   GALEJS
 * more #include tests
 * 
 *    Rev 1.58   21 Jan 1999 13:51:38   GALEJS
 * standardize #include tests
 * 
 *    Rev 1.57   12 Jan 1999 18:28:44   GALEJS
 * move EXTERN dcls
 * 
 *    Rev 1.56   22 Jun 1998 18:09:06   GALEJS
 * mkae Intellifont reentrant too
 * 
 *    Rev 1.55   15 Jun 1998 15:25:22   GALEJS
 * reentrancy parm-passing changes
 * 
 *    Rev 1.54   15 Apr 1998 17:32:22   GALEJS
 * move GLOBAL hchar_buf to IF_STATE (also chr_def_hdr)
 * 
 *    Rev 1.53   14 Apr 1998 18:53:04   GALEJS
 * fontindex now in IF_STATE; hiword/loword now local
 * 
 *    Rev 1.52   02 Apr 1998 18:44:28   GALEJS
 * move 2 GLOBALs into if_state
 * 
 *    Rev 1.51   24 Mar 1998 15:49:20   GALEJS
 * include-file changes
 * 
 *    Rev 1.50   20 Mar 1998 11:41:50   GALEJS
 * 64-bit port
 * 
 *    Rev 1.49   20 Mar 1998 09:52:42   JOE
 * In DArd_char(), the statement "tmp_fc.font_hdr = (LPUB8)0" should be
 * conditionally compiled based on (PCLEO_RDR || NON_IF_FONT || DYNAMIC_FONTS)
 * 
 *    Rev 1.48   14 Jan 1998 14:13:32   GALEJS
 * delete unused extern
 * 
 *    Rev 1.47   19 Sep 1997 11:22:34   JOE
 * In DArd_char(), added initialization statements for tmp_fc members
 * ssnum and font_hdr to handle Purify errors occurring in BUCKfind()
 * (by jwd).
 * 
 *    Rev 1.46   16 Sep 1997 15:01:12   GALEJS
 * fix compile for ARM/Helios
 * 
 *    Rev 1.45   04 Aug 1997 10:22:54   JOE
 * In "ifload_font()", conditionally compiling "status" based on
 * "!ROM !! DYNAMIC_FONTS" to resolve compiler error.
 * 
 *    Rev 1.44   31 Jul 1997 16:25:24   JOE
 * Conditionally compiled local variable to resolve unreferenced variable
 * warning (by Jimmy).
 * 
 *    Rev 1.43   24 Jul 1997 16:20:08   JOE 
 * Got rid of unreferenced local variables (by Jimmy).
 * 
 *    Rev 1.42   16 Jul 1997 16:47:24   JOE 
 * Got rid of 1 warning message about type mismatch (by Jimmy).
 * 
 *    Rev 1.41   30 Jun 1997 10:02:20   JOE
 * Fixed problem getting the width of character 0xffff (by Jimmy).
 * 
 *    Rev 1.40   18 Jun 1997 18:38:30   GALEJS 
 * allow compile for PTV_OS
 * 
 *    Rev 1.39   16 Jun 1997 17:14:40   GALEJS
 * compile under PSOS
 * 
 *    Rev 1.38   02 Jan 1997 15:25:06   DAVID 
 * Fixed bug in FNseek-read.  Changed UW16 to int, for Asian Mapping Tables
 * greater than 64K.
 * 
 *    Rev 1.37   07 Nov 1996 13:23:48   JOE 
 * In ifget_FontBBox(), store threshold value in "if_state".
 * 
 *    Rev 1.36   20 Mar 1996 12:27:10   MERRILL
 * save a line of code and several warnings about#if PCLEO_RDR  || (IF_PCLEOI && IF_ROM)
 * 
 *    Rev 1.35   29 Feb 1996 10:09:08   MIKE
 * Made "hchar_buf" conditional (IF, PS) to save BUFFER pool memory
 * 
 *    Rev 1.34   29 Jan 1996 15:01:42   MIKE
 * Fixed "functions declared but never used" warnings
 * 
 *    Rev 1.33   05 Dec 1995 15:10:50   MERRILL
 * quiet amb. assignment
 * 
 *    Rev 1.32   13 Jul 1995 14:12:22   MIKE
 * Conditionally compile char_dir() and fgseg() for IF_RDR=1
 * 
 *    Rev 1.31   18 Apr 1995 16:50:32   JOE
 * In LIBmake_cd() and DArd_char(), added support for the removal of
 * symbol set mapping.
 * 
 *    Rev 1.30   06 Apr 1995 15:14:48   LISA
 * Changed copyright from Miles Inc. to Bayer Corp.
 * 
 *    Rev 1.29   19 Jan 1995 11:30:22   JOE
 * In LIBmake_cd(), conditionally compiled check of "missing_ccparts"
 * based on FCO_RDR && SLIM_FONTS.
 * 
 *    Rev 1.28   18 Jan 1995 13:27:02   JOE
 * In LIBmake_cd(), if character processed was not an external compound
 * character, reset "cgnum" and "index" fields of CHR_DEF data so that
 * fco_set_char() check for external compound character will work.
 * 
 *    Rev 1.27   16 Jan 1995 14:07:00   JOE
 * In LIBmake_cd(), if processing external compound character, return
 * ERR_no_cc_part if FCO_RDR so as to bypass the code which searches
 * IF plugins for missing character.
 * 
 *    Rev 1.26   22 Apr 1994 16:07:52   JOE
 * Changed conditional compile statement prior to including <hif.h>
 * to #if (_AM29K && !UNIX) to resolve UNIX Metaware compiler error.
 * 
 *    Rev 1.25   22 Apr 1994 13:55:10   LISA
 * Made modifications to copyright/disclaimer notice.
 * 
 *    Rev 1.24   09 Feb 1994 11:53:12   JOE
 * More _AM29K changes.
 * 
 *    Rev 1.23   02 Feb 1994 08:52:50   JOE
 * 
 * AM29K changes.
 * 
 *    Rev 1.22   15 Dec 1993 08:43:34   JOE
 * 
 * Fixed prohibit flag problem for external compouond characters.
 * 
 *    Rev 1.21   08 Dec 1993 18:59:06   ROB
 * General cleanup for MSDOS, FLAT, OS2.
 * 
 *    Rev 1.20   12 Oct 1993 09:47:18   MAIB
 * Added ansi defs checks to allow compilation on sparc
 * 
 *    Rev 1.19   11 Oct 1993 12:26:24   MIKE
 * chr_def_hdr.mirror_flags in LIBmake_cd().
 * 
 *    Rev 1.18   20 Aug 1993 17:29:48   JOE
 * 
 * If MIPS, do not include "stdlib.h" or "io.h" to resolve compiler
 * errors.
 * 
 *    Rev 1.17   15 Jun 1993 17:23:20   MIKE
 * In ifunload_font(), move "if (b->tfnum == if_state.if_init_face) ... ;"
 * to top of function.
 * 
 *    Rev 1.16   15 Jun 1993 10:35:34   JOE
 * Moved "vxWorks.h" before "port.h" to resolve conflicts.
 * 
 *    Rev 1.15   12 May 1993 15:58:38   ROB
 * Clean up compiler warnings - nested comments.
 * 
 *    Rev 1.14   06 May 1993 15:12:12   JOE
 * In DArd_char(), do not save and restore font index. Restoring the font
 * index inside DArd_char() causes a core dump when processing an HQ2 pcleo
 * compound character. Instead, save and restore font index in calling routine
 * (ifmake_gaso_and_stats()).
 * 
 *    Rev 1.13   30 Apr 1993 10:10:34   MIKE
 * Fixed problems in DYNAMIC_FONTS/ROM (ifload_font, find_bucket_type, SEEKREAD)
 * 
 *    Rev 1.12   22 Apr 1993 11:15:48   MIKE
 * Debugged and optimized ROM code in FMprocess_face().
 * Moved ifget_FontBBox() from cgif.c. This module is a more logical place.
 * 
 *    Rev 1.11   20 Apr 1993 10:56:42   MIKE
 * Added new function FMprocess_face(), called from ifload_font(), to read IF
 * face in library file format. This mimics ixmak for font that are not part
 * of the if.fnt block. Conditionally compiled with DYNAMIC_FONTS.
 * 
 *    Rev 1.10   15 Mar 1993 09:52:12   JOE
 * In DArd_char(), if call to LIBmake_cd() fails, restore "fontindex" before
 * returning error.
 * 
 *    Rev 1.9   15 Mar 1993 09:00:30   JOE
 * In DArd_char(), added HQ2 optimization for IF_PCLEOI && IF_ROM.
 * 
 *    Rev 1.8   02 Mar 1993 14:34:18   LISA
 * Put Log information back into header.
 *
 *    Rev 1.7   15 Feb 1993 12:19:42   JOE
 * In rd_char(), restructured conditional compile block because of MIPS
 * compiler bug.
 *
 *    Rev 1.6   12 Feb 1993 13:44:00   JOE
 * VXWorks support.
 *
 *    Rev 1.5   07 Jan 1993 15:31:50   JOE
 * Corrected ANSI function declaration for LIBmake_cd().
 *
 *    Rev 1.4   06 Jan 1993 16:18:00   JOE
 * ANSI C function declaration changes.
 *
 *    Rev 1.3   05 Jan 1993 08:38:58   JOE
 * 960 changes (multiple "READ"s if reading more than 996 bytes due to 
 * limitation of INTEL library routine, conditional calls to routine
 * FMalloc_rd() due to difference in argument list).
 *
 *    Rev 1.2   14 Dec 1992 15:58:52   LISA
 * Removed CntrlZ character from end of file.
 * 
 *    Rev 1.0   09 Dec 1992 15:38:22   LISA
 * Initial revision.
*/
/* $Date:   Dec 14 2004 14:17:46  $ */
/* fm.c */
/*
 *
 *
 *  HISTORY:
 *
 *  12-Mar-90   jfd     Storing the pointers to the Typeface Header
 *                      and Font Alias Segments in this routine now
 *                      (keys 107 and 110)
 *  05-May-90   awr     Character buffer is fixed size- allocated once
 *  07-Jun-90   dah     Modified FMalloc_rd() and FMseek_read(); added
 *                      parameters for font library compression.
 *  08-Jun-90   dET     Close files at end of functions because Windows
 *                      is brain dead.
 *  29-Jul-90   awr     Fixed FMrd_char. Was clobbering cd->index with
 *                      with index into update library. Later, old library
 *                      becomes active- meaningless index.
 *  12-Oct-90   dET     Close files at end of functions if running either
 *                      WINDOWS or BOW
 *  04-Dec-90  jfd      Moved "include" statement for  "cgconfig.h" to line
 *                      following "port.h"
 *  19-Dec-90  jfd      IFB on a Printer changes:
 *                      1.) In FMrd_char(), when calling IXget_fnt_index(),
 *                          pass (FONTCONTEXT *) instead of (LONG).
 *                      2.) Add ROM support.
 *  08-Jan-91  jfd      IFB on a Printer changes:
 *                      1.) Added PCLEO support.
 *  13-Jan-91  awr      Changed FMalloc_rd() to call BUFalloc()
 *  28-Jan-91  jfd      Made size arg of MEMalloc() LONG
 *  30-Jan-91  dET      Made modifications to FMseek_read and function
 *                      prototyping for multi-model compilation.  Added new
 *                      include for mixmodel.h and memory.h
 *   4-Feb-91  awr      Changed symbol set mapping to use SYMmap()
 *   9-Feb-91  awr      Added #include "sym.h" to declare symbol set fncts.
 *  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 LIBload_font(), changed field name pfont_block to
 *                      pfnt_index.
 *  15 May 91  ss       Deleted all references to COMPRESS.  This includes
 *                        deleting last 2 parameters to FMalloc_rd() &
 *                        FMseek_read() which are no longer needed.
 *                      Added support for SLIM_FONTS (external compound chars).
 *                      Changes to support up to 5 level, 15 plugin scheme.
 *   3 Jun 91  ss       Save mirror flags for SLIM_FONT compound chars.
 *  05-Jun-91  jfd      Changed FMrd_char to use a temp FONTINDEX for HQ3
 *                      and ROM processing.
 *                      (FIX FROM EARLIER VERSION)
 * 
 *                      SUN support
 *                      (FIX FROM EARLIER VERSION)
 *
 *                      Moved debug.h after port.h
 *                      (FIX FROM EARLIER VERSION)
 *   9-Jun-91  awr      Changed chr_def_hdr structure
 *  18 Jun 91  ss       Fixed bug in LIBmake_cd for SLIM_FONTS, not finding
 *                      all the pieces of an external compound char.
 *                      And bug searching too many buckets of a compound
 *                      character - was searching buckets the TF didn't "own".
 *  19 Jun 91  ss       Changed CHR_DEF.bucknum to CHR_DEF.buck_search_lvl.
 *                      Changed mirror code to use defines for masks.
 *  26 Jun 91  ss       Added casts for b->plibfont usage.
 *   1 Jun 91  ss       Added prototpye for fgseg() in not LINT_ARGS.
 *  07-Aug-91  jfd      Changed "MSWINDOWS" to "_WINDOWS".
 *                      In function prototype for "clear_mem()", changed
 *                      type of first argument from "UBYTE *" to "PUBYTE"
 *  17 Jul 91  ss       Updated code for SLIM_FONTS mirroring to work with
 *                      code added elsewhere.
 *  24-Aug-91  awr      Moved function decls to include file
 *  17 Sep 91  ss       Added line in rd_char() to test if OK to call IXopen()
 *                      based on !ROM and PCLEO_RDR for reading a disk based
 *                      library (like plugins) and PCLEO_RDR is enabled.
 *                      Also in rd_char(), added set of expand_buf for !ROM
 *                      and PCLEO_RDR case.
 *   2 Oct 91  ss       Changed PCLEO_RDR code in rd_char() to use only the
 *                      EXPBUFSIZE # of bytes now that it is larger.
 *   4 Oct 91  ss       Added SPARC support.
 *  18 Oct 91  jfd      Changed "char_dir" from MLOCAL to GLOBAL.
 *  25 Oct 91  ss       Added return lines in LIBmake_cd().
 *   3-Jan-92  awr      Removed font_open field from BUCKET
 *   7-Jan-92  jfd      In rd_char(), conditionally compiled line which
 *                      references "cd->pgif" based on PCLEO_RDR.
 *   5-Feb-92  rs       Cleanup of compiler warnings.
 *  21 Feb 92  ss       In LIBload_font(), make sure setting of globoff
 *                      avoids alignment problems.
 *   4 Mar 92  ss       Updated references to entries in new bucket structure
 *                      in ROM code.
 *   7-Mar-92  awr      Changed for UFST
 *  10 mar 92  ss       Added prototypes for PCLload_font().
 *                      Fixed tests for PCLEO_RDR in ifload_font().
 *  24 Mar 92  ss       Fixed set of charcount and charoff in rd_char() for
 *                      SPARC specific code.
 *  30 Mar 92  ss       Fixed set of charcount and charoff for SPARC and SLIM.
 *  31 Mar 92  ss       Added line needed for last fix which got lost somehow.
 *  03-Apr-92  rs       Portability cleanup (port.h).
 *  23 Apr 92  ss       In LIBmake_cd(), changed limit of test for searching
 *                      bucket tree for missing cc chars fro NBUCKET_LEVELS
 *                      to fontindex.num_searches. This is works with the
 *                      new plugin scheme of not referencing TFS face via
 *                      fontindex.icur_index[0].
 *   7 May 92  ss       Changed arg to IXopen_file() in rd_char().
 *  16-Jun-92  ss       In DArd_char(), if not HQ3, when checking if pcleo,
 *                      check "fi_sav.extern_font", rather than calling
 *                      "B_ISEXTERN(b)", because BUCKfind() changes value
 *                      of "b->bucket_num".
 *   1 Jul 92  ss       Moved port.h to top to access defines earlier.
 *                      Changed conditional on SUN to UNIX to be more general.
 *   9-Jul-92  jfd      In DArd_char(), if not HQ3, load "tmp_fc.font_id" 
 *                      with "-(fontindex.cur_tf_num)" if at TFS level, and
 *                      with "-(fontindex.pix->tfnum)" if at plugin level.
 *   5-Aug-92  jfd      Removed function prototypes for "clear_mem()".
 *                      Never references here.
 *  09-Aug-92  rs       Changes for Watcom C386 (string.h).
 *                      Change args in FMseek_read() & FMalloc_read
 *                      from SW16 to int, SL32 to long for 32 bit platforms.
 *  21-Aug-92  rs       Fix for case where we have a non-Intellifont primary
 *                      font which does not contain the desired character and
 *                      the character ends up being a compound char with a part in the
 *                      universals (ie PB symbol set, chId 82 - Rx prescription).
 *  15-Sep-92  jfd      Conditionally compiled the following routines:
 *                      ifload_font(), ifunload_font(), ifset_char(),
 *                      LIBmake_cd(), DArd_char(), rd_char(), FMchar_index().
 *  23-Sep-92  jfd      INTEL960 conditional compile changes.
 *  25-Sep-92  jfd      Replaced CGSPARC.H with CGMACROS.H.
 *  28-Sep-92  awr      Changed parameters of BUCKfind()
 *  30-Sep-92  jfd      Removed conditional compiles based on SPARC and
 *                      replaced with conditional compiles based on
 *                      (NAT_ALIGN == 4) and/or (BYTEORDER == HILO) wherever 
 *                      possible.
 *  09-Oct-92  mby      SYMmap() calls take second argument (int fst_type).
 *  15-Oct-92  jfd      In rd_char(), added special block of code to get
 *                      offset to character and size of character for
 *                      INTEL 960.
 *  15-Nov-92  rs       Port to Macintosh - no io.h, include unix.h.
 *  05-Jan-93  jfd      Conditionally compiled calls to Fmalloc_rd()
 *                      based on platform due to different arguments.
 *                      In FMseek_read(), if INTEL960, if reading more 
 *                      than 996 bytes, use multiple READs due to
 *                      problem with 960 read() function.
 *  06-Jan-93  jfd      ANSI C function declaration changes.
 *  07-Jan-93  jfd      Corrected ANSI function declaration for LIBmake_cd().
 *  08-Feb-93  jfd      VXWorks support.
 *                      Changed all READ's to READF's due to conflict with
 *                      VXWorks.
 *  15-Feb-93  jfd      In rd_char(), changed "#if ...#elif ...#else" block to
 *                      "if ... #else ... #if ... #else" because of MIPS
 *                      compiler bug.
 *  10-Mar-93  jfd      In DArd_char(), added support for HQ2 processing
 *                      optimization for (IF_PCLEOI && IF_ROM).
 *  15-Mar-93  jfd      In DArd_char(), if call to LIBmake_cd() fails,
 *                      restore "fontindex" before returning error.
 *  14-Apr-93  mby      Changed ifload_font() to handle dynamic fonts.
 *                      Added function FMprocess_face(), called from
 *                      ifload_font(), to read IF face in library file format.
 *                      Conditionally compiled based on DYNAMIC_FONTS.
 *  19-Apr-93  mby      Added macros to FMprocess_face() to handle SPARC-like
 *                      platforms that require special byte alignment.
 *  21-Apr-93  mby      Moved ifget_FontBBox() from cgif.c. Optimized ROM code.
 *  29-Apr-93  mby      Fixed problems in DYNAMIC_FONTS/ROM in ifload_font()
 *                      & find_bucket_type(). Fixed SEEKREAD macro.
 *  06-May-93  jfd/ss   In DArd_char(), do not restore font index until we
 *                      are completely done with the character. Restoring
 *                      the font index inside DArd_char() causes a core
 *                      dump when processing an HQ2 pcleo compound character.
 *                      Save and restore font index in calling routine
 *                      (ifmake_gaso_and_stats()).
 * 12-May-93  rs        Remove nested comment in 'find_bucket_type()'.
 * 14-Jun-93  mby       In ifunload_font() move 'if (b->tfnum == ...
 *                      if_state.if_init_face = 0;' to top of function.
 * 15-Jun-93  jfd       Moved "vxWorks.h" before "port.h" to resolve conflicts.
 * 20-Aug-93  jfd       If MIPS, do not include "stdlib.h" or "io.h" to
 *                      resolve MIPS compiler error.
 * 08-Oct-93  mby       Set chr_def_hdr.mirror_flags to 0 at the end of
 *                      LIBmake_cd(), if the function fails.
 * 10-Oct-93  maib      Added ansi def checks around ifget_FontBBox
 * 08-Dec-93  rs        General cleanup - MSDOS & CGFLAT32.
 * 15-Dec-93  jfd       In LIBmake_cd(), save prohibit flag and width when
 *                      processing an external compound character.
 * 26-Jan-94  jfd       Removed #include for fcntl.h.
 *                      Conditionally compiled out #include for "unistd.h"
 *                      (if !_AM29K).
 * 04-Feb-94  jfd       Conditionally compiled #include for io.h based on
 *                      !_AM29K.
 *                      Including hif.f if _AM29K.
 * 22-Apr-94  jfd       Changed conditional compile statement prior to
 *                      including <hif.h> to #if (_AM29K && !UNIX) to
 *                      resolve UNIX Metaware compiler error.
 * 13-Jan-95  jfd       In LIBmake_cd(), if processing external compound
 *                      character, return ERR_no_cc_part error if FCO_RDR
 *                      so as to bypass the code which searches
 *                      IF plugins for missing character.
 * 18-Jan-95  jfd       In LIBmake_cd(), if character processed was not an
 *                      external compound character, reset "cgnum" and
 *                      "index" fields of CHR_DEF data so that fco_set_char()
 *                      check for external compound character will work.
 * 19-Jan-95  jfd       In LIBmake_cd(), conditionally compiled check of
 *                      "missing_ccparts" based on FCO_RDR && SLIM_FONTS. 
 * 18-Apr-95  jfd       In LIBmake_cd() and DArd_char(), added support 
 *                      for the removal of symbol set mapping.
 * 13-Jul-95  mby       Conditionally compile char_dir() and fgseg() for
 *                      IF_RDR=1. "b->p.in" is not defined otherwise.
 * 29-Jan-96  mby       Fixed "functions declared but never used" warnings.
 * 27-Feb-96  mby       Made hchar_buf declaration conditional on IF_RDR || PST1_RDR.
 * 07-Nov-96  jfd       In ifget_FontBBox(), store threshold value in
 *                      "if_state".
 * 01-Jan-97  dlk       Fixed bug in FNseek_read.  Changed (UW16) to (int) in
 *                      the 'if' test for READF returning the correct 'count' of
 *                      bytes.  This was to support reading Asian Mapping Tables
 *                      larger than 64K bytes.
 * 16-Jun-97  slg        Allow PSOS compilation
 * 18-Jun-97  slg        Allow PTV_OS compilation
 * 04-Aug-97  jfd    In "ifload_font()", conditionally compiling "status"
 *                   based on "!ROM || DYNAMIC_FONTS" to resolve compiler
 *                   error.
 * 16-Sep-97  slg    Fix compile for ARM/Helios
 * 16-Sep-97  jwd    In DARD_char(), added initialization statements for tmp_fc
 *                   members ssnum and font_hdr, to handle Purify errors occur-
 *                   ring in BUCKfind().
 * 20-Mar-98  jfd    In DArd_char(), the statement "tmp_fc.font_hdr = (LPUB8)0"
 *                   should be conditionally compiled based on (PCLEO_RDR ||
 *                   NON_IF_FONT || DYNAMIC_FONTS).
 * 20-Mar-98  slg    Don't use "long" dcls (incorrect if 64-bit platform); 
 *                    also integrate Jim's Alpha-port change
 * 02-Apr-98  slg    Move GLOBALs missing_ccparts and missing_ccpart_widthinfo
 *                    into IF_STATE.
 * 14-Apr-98  slg      Vbls hiword, loword must now be declared locally in 
 *                  all functions that use MAKELONG. 
 * 15-Apr-98  slg    Move GLOBAL hchar_buf into IF_STATE.
 * 16-Feb-99  ks    Added 'v' intellifont file format support to FMprocess_face().
 * 28-July-99 ks    Changed DEBUG compiler directive to AGFADEBUG.
 * 28-Jan-00  slg    Replace !ROM tests by DISK_FONTS; compile fix in find_bucket_type(). 
 * 15-Mar-00  ks    Put in IF 'v' format change in FMprocess_face().
 * 24-Aug-01  jfd   Added function MSL_to_CG_index().
 *                  In DArd_char(), call MSL_to_CG_index() to extract CG #
 *                  prior to lookup in HQ3 table.
 *            jwd   DISK / ROM changes.
 * 27-Aug-01  jfd   In DArd_char(), removed conditional compile surrounding setting
 *                  of "tmp_fc.ExtndFlags" to 0. (In FONTCONTEXT structure, this
 *                  field used to be conditionally compiled, but no longer is.)
 * 31-Aug-01  dz    Changed for 64-bit/BYTEORDER == HILO platform to use macro MAKELONG 
 * 28-Mar-02  jfd   In DArd_char(), if unbound pcleo, call SYMmap() instead of MSL_to_CG_index()
 *                  for cg number.
 *
 */

#include "cgconfig.h"

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

#include "ufstport.h"

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

#if (defined(_AM29K) && !defined(SUN))
#include <hif.h>  /* 2-7-94 jfd */
#endif

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

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

#include <string.h>

#if MAYBE_MEMORY_H
#include <memory.h>
#endif

#include "dbg_ufst.h"
#include "shareinc.h"

#include "mixmodel.h"
#include "segments.h"

#include "cgmacros.h"

#ifdef LINT_ARGS  /* function prototypes 30-Jan-91 dET */

#if IF_RDR
GLOBAL LPSB8      char_dir(FSP PBUCKET);
MLOCAL UW16       rd_char(FSP PCHR_DEF);
MLOCAL SW16       FMchar_index(FSP PBUCKET, UW16);
MLOCAL SW16       MSL_to_CG_index(FSP UW16);    /* 08-13-01 jfd */
#endif  /* IF_RDR */

#if DYNAMIC_FONTS && IF_RDR
MLOCAL UW16       FMprocess_face(FSP LPUB8, PBUCKET);
MLOCAL BOOLEAN    find_bucket_type(FSP PBUCKET, LPUB8, UL32, SL32, SW16*);
#endif

#else             /* NOT LINT_ARGS */
/* fm.c */
#if IF_RDR
GLOBAL LPSB8      char_dir();
MLOCAL UW16       rd_char();
MLOCAL SW16       FMchar_index();
MLOCAL SW16       MSL_to_CG_index();    /* 08-13-01 jfd */
#endif  /* IF_RDR */

/* mem.c */

#if DYNAMIC_FONTS && IF_RDR
MLOCAL UW16       FMprocess_face();
MLOCAL BOOLEAN    find_bucket_type();
#endif
#endif

#if IF_RDR    /* 08-10-01 jfd */
MLOCAL  UW16 MSL_nums[] = { 21,   55, 56, 86,  124,  125,  127, 148,  182, 1001, 1090, 1091 };
MLOCAL    UW16 CG_nums[]  = { 1595, 38, 48,  1, 1700, 1725, 1703, 172, 1675, 1622,  175,  173 };

#if defined (ANSI_DEFS)    /* 08-13-01 jfd */
MLOCAL SW16       MSL_to_CG_index(FSP UW16 MSL_num)
#else
MLOCAL SW16       MSL_to_CG_index(MSL_num)
    UW16 MSL_num;
#endif
{
    UW16 i;

    for (i=0; i<sizeof(MSL_nums); i++)
    {
        if (MSL_num == MSL_nums[i])
            return i;
    }
    return -1;
}
#endif    /* IF_RDR */

#if DISK_FONTS

/*------------------*/
/*  FMseek_read     */
/*------------------*/
/*  In file "f", do an lseek to "offset" an then read "count" bytes
 *  into "buffer". Return TRUE if success.
 */
#if defined (ANSI_DEFS)
GLOBAL BOOLEAN FMseek_read(FSP SL32 f, SL32 offset,
#if USING_16_BIT_DOS    /* 16 bit platform */
    UW16 count,
#elif defined(__i960)
    UL32 count,
#else                     /* 32 bit platform */
    SL32 count,
#endif
    LPSB8 buffer)
#else
GLOBAL BOOLEAN
FMseek_read(f, offset, count, buffer)
    SL32   f;       /* file handle - SW16 to int - 8/10/92 - rs  */
    SL32   offset; /* offset within file - SL32 to long - 8/10/92  */
#if USING_16_BIT_DOS        /* 16 bit platform */
    UW16  count;   /* number of SB8s to read */
#elif defined(__i960)
    UL32 count;
#else                        /* 32 bit platform */
    SL32   count;   /* number of SB8s to read - SW16 to int 8/10/92 */
#endif
    LPSB8  buffer; /* buffer to read data into */
#endif
{
#if defined (__i960)
    UL32 num_read;
    UL32 maxcount;
    UL32 loops;
    UL32 left;
    LPSB8  buffer2;
    UL32 i;
#endif

#if USING_16_BIT_DOS    /* 16 bit platform */
    DBG2("                FMseek_read()   offset: %ld   count: %u\n",
                                                          offset, count);
#else                    /* 32 bit platform */
    DBG2("                FMseek_read()   offset: %ld   count: %ld\n",
                                                          offset, count);
#endif
    if(LSEEK(f, offset, SEEK_SET) != offset)
    {
        DBG("                    lseek() failed\n");
        return FALSE;
    }
#if !defined(__i960)
    if((SL32)READF(f, buffer, count) != count)
    {
        DBG("                    read() failed\n");
        return FALSE;
    }
#else
    /* For INTEL960, can't read more than 996 bytes at a time,
       so break up read() call into multiple reads if necessary
     */

    if (count <= 996)
    {
       num_read = READF(f, buffer, count);
       if (num_read != count)
       {
          DBG("                    read() failed\n");
          return FALSE;
       }
    }
    else
    {
       maxcount = 996;
       loops = count / maxcount;
       left  = count - (loops * maxcount);

       buffer2 = buffer;
       for (i=0; i<loops; i++)
       {
          num_read = READF(f, buffer2, maxcount);
          if (num_read != maxcount)
          {
            DBG("                    read() failed\n");
            return FALSE;
          }
          buffer2 += maxcount;
       }
       num_read = READF(f, buffer2, left);
       if (num_read != left)
       {
         DBG("                    read() failed\n");
         return FALSE;
       }
    }
#endif  /* !defined(__i960) */
    return TRUE;
}

/*------------------*/
/*  FMalloc_rd      */
/*------------------*/
/*  MEMalloc "size" SB8s and then do an lseek() to "offset" in file "f" and
 *  read "size" SB8s into the allocated buffer. Return the buffer pointer
 *  or null on failure.
 */
#if defined (ANSI_DEFS)
GLOBAL MEM_HANDLE FMalloc_rd(FSP SL32 f, 
#if USING_16_BIT_DOS    /* 16 bit platform */
    UW16 size,
#else                    /* 32 bit platform */
    SL32 size,
#endif
    SL32 offset)
#else
GLOBAL MEM_HANDLE
FMalloc_rd(f, size, offset)
    SL32    f;      /* SW16 to int - 8/10/92 - rs */
#if USING_16_BIT_DOS    /* 16 bit platform */
    UW16   size;   /* Size of buffer to allocated */
#else                     /* 32 bit platform */
    SL32    size;   /* Size of buffer to allocated - SW16 to int - 8/10/92 */
#endif
    SL32   offset; /* SL32 to long - 8/10/92 */
#endif
{
    MEM_HANDLE hbuf;
    LPSB8      buf;

  /*  Acquire size SB8S  */
    hbuf = BUFalloc(FSA (SL32)size);
    if( !hbuf )
      return NIL_MH;
    buf = (LPSB8)MEMptr(hbuf);

  /*  Read data into new buffer.  If error, free buffer  */

    if(!FMseek_read(FSA f, offset, size, buf))
    {
        BUFfree(FSA hbuf);
        return NIL_MH;
    }

    return hbuf;
}

#endif  /* DISK_FONTS */

#if IF_RDR


#if defined (ANSI_DEFS)
MLOCAL UW16 maybe_cleanup_files(FSP PBUCKET b, UW16 returnstatus)
#else
MLOCAL UW16 maybe_cleanup_files(b, returnstatus)
PBUCKET    b;
UW16 returnstatus;
#endif
{
#if (defined(_WINDOWS) | defined(BOW))   /* 10-12-90 dET */
      /* brain dead Windows does not allow open files */
        IXclose_file(FSA b);
#endif
        return returnstatus;
         
}    /* maybe_cleanup_files */


/*------------------*/
/*    char_dir      */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL LPSB8 char_dir(FSP PBUCKET b)
#else
GLOBAL LPSB8
char_dir(b)
    PBUCKET b;
#endif
{
#if IF_ROM
    return b->p.in.pface_header_seg + 6;
#endif
#if IF_DISK
    return ((LPSB8)MEMptr(b->p.in.hface_header_seg)) + 6;
#endif
#if (!IF_DISK && !IF_ROM)    /* presumably IF_PCLEOI */
    return b->p.in.pface_header_seg + 6;
#endif
}


/*------------------*/
/*     fgseg        */
/*------------------*/
#if defined (ANSI_DEFS)
GLOBAL LPSB8 fgseg(FSP PBUCKET b)
#else
GLOBAL LPSB8
fgseg(b)
    PBUCKET b;
#endif
{
#if IF_ROM
    return b->p.in.pfgseg;
#endif
#if IF_DISK
    return (LPSB8)MEMptr(b->p.in.hfgseg);
#endif
#if (!IF_DISK && !IF_ROM)    /* presumably IF_PCLEOI */
    return b->p.in.pfgseg;
#endif
}


/*-------------------*/
/*   ifunload_font   */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16 ifunload_font (FSP PBUCKET  b)
#else
GLOBAL UW16 ifunload_font (b)
    PBUCKET  b;
#endif
{
    DBG ("\nifunload_font()\n");

    if (b->tfnum == if_state.if_init_face)
       if_state.if_init_face = 0;

#if PCLEO_RDR
    if(b->extern_font)
       {
       if (b->extern_font == PCL_BITMAP_FONT)   /* jwd, 07/21/03 */
          return SUCCESS;
       else
          BUFfree(FSA b->p.in.hfgseg);   /* all we need to do for PCLEOs */
       }
    else
#endif
    {
      /*  Either disk or ROM library file */

#if DISK_FONTS
        IXclose_file(FSA b);
#endif  /*  DISK_FONTS  */

        if(!B_ISROM(b))
        {
            BUFfree(FSA b->p.in.hface_header_seg);
            BUFfree(FSA b->p.in.hfgseg);
        }
    }
    return SUCCESS;


/*-------------------*/
/*    ifload_font    */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  ifload_font(FSP PFONT_DES pfd, PBUCKET b)
#else
GLOBAL UW16
ifload_font(pfd, b)
    PFONT_DES    pfd;
    PBUCKET      b;
#endif
{
    LPSB8   face_header_seg=NULL;   /* Face header seqment (char dir)   */
    LPSB8   chptr;             /* Standard character directory     */
    UW16    dir_entry_size;    /* size of char directory entry     */
    UW16    ch_count;          /* number of character in directory */

    SL32     globoff;           /* offset to face global segment    */
    UW16    globcount;         /* size of face global segment      */
    LPSB8    p;

#if (BYTEORDER == HILO || (NAT_ALIGN >=4 && BYTEORDER == LOHI)) /* Motorola format, don't swap bytes */
    UW16    hiword, loword;                                      /* 08-31-01 dz */
#endif

#ifdef AGFADEBUG
    UW16    type;
    UL32    size;
#endif

    UW16    key;
    UL32    off;
    UW16    count;
    UW16    oseg;

    DBG("    ifload_font()\n");

#if PCLEO_RDR
    if( b->extern_font)               /* Is this a PCLEO ? */
       return PCLload_font(FSA (LPUB8)pfd, b);
#else
    pfd=pfd;/*nop*/
#endif  /* PCLEO_RDR  */
#if DYNAMIC_FONTS
    if (b->dynIFActive)
    {
    UW16    status;

        status = FMprocess_face(FSA (LPUB8)pfd, b);
        if (status)  return status;
        b->tfnum = if_state.fontindex.dynix.tfnum;
        b->bucket_num = if_state.fontindex.dynix.bucket_num;
    }
    else
#endif  /* DYNAMIC_FONTS */

    {
      b->tfnum      = if_state.fontindex.pix->tfnum;
      b->bucket_num = if_state.fontindex.pix->bucket_num;
    }

#if IF_ROM
#if DYNAMIC_FONTS
    if (b->dynIFActive)
    {
      b->p.in.plibfont = b->cur_font_hdr;
      face_header_seg = b->p.in.pface_header_seg 
                      = (LPSB8)b->p.in.plibfont + if_state.fontindex.dynix.fhoff;
    }
    else
#endif  /* DYNAMIC_FONTS */
    {
      b->p.in.plibfont = if_state.fontindex.pfnt_index + if_state.fontindex.pix->p_r.lib_offset;
      face_header_seg = b->p.in.pface_header_seg 
                      = (LPSB8)b->p.in.plibfont + if_state.fontindex.pix->fhoff;
    }
#endif    /* IF_ROM */
#if IF_DISK 
   {
    MEM_HANDLE  hfhseg;
    UW16    status;

  /* Open library file */

    status = IXopen_file(FSA if_state.fontindex.pix, b);
    if (status)
        return status;

  /* Read face header (= character directory) */

    DBG("        face_header (=character directory)\n");

#if USING_16_BIT_DOS    /* 16 bit platform */
#if DYNAMIC_FONTS
    if (b->dynIFActive)
        hfhseg = FMalloc_rd(FSA b->fh, if_state.fontindex.dynix.fhcount,
                                   if_state.fontindex.dynix.fhoff);
    else
#endif  /* DYNAMIC_FONTS */
        hfhseg = FMalloc_rd(FSA b->fh, if_state.fontindex.pix->fhcount,
                                   if_state.fontindex.pix->fhoff);
#else
#if DYNAMIC_FONTS
    if (b->dynIFActive)
        hfhseg = FMalloc_rd(FSA b->fh, 
             (SL32)if_state.fontindex.dynix.fhcount, if_state.fontindex.dynix.fhoff);
    else
#endif  /* DYNAMIC_FONTS */
        hfhseg = FMalloc_rd(FSA b->fh, 
             (SL32)if_state.fontindex.pix->fhcount, if_state.fontindex.pix->fhoff);
#endif    /* USING_16_BIT_DOS */ 
    if ((b->p.in.hface_header_seg = hfhseg) == NIL_MH)
    {
        IXclose_file(FSA b);
        return ERR_mem_face_hdr;
    }
    face_header_seg = (LPSB8)MEMptr(b->p.in.hface_header_seg);

   }
#endif  /* IF_DISK */

  /*  Set up character directory   (skip segment link)  and count characters
   */

  /* Count number of characters in directory */

    ch_count = 0;

    /* use defines set in segments.h for correct size on SPARC -ss 8/28/91 */
    if(B_U_LIB(b))
       dir_entry_size = US_CH_DIR_ENTRY_SIZE;
    else 
       dir_entry_size = CH_DIR_ENTRY_SIZE;

    chptr = char_dir(FSA b);
    while(*(LPUW16)chptr != MAX_UWORD)
    {
        ch_count++;
        chptr += dir_entry_size;
    }

    b->p.in.ch_count = ch_count;

  /* Type face global segment */

#if (NAT_ALIGN >= 4 )  /* 08-31-01 dz */   /* compensate for potential alignment problems -ss 2/21/92 */
                       /* changed from "ifdef SPARC" - jfd 9/30/92 */
    MAKELONG( globoff, face_header_seg);        /* file offset    */
#else
    globoff = *(LPSL32)(face_header_seg);        /* file offset    */
#endif
    globcount = *(LPUW16)(face_header_seg + 4); /* segment length */


    DBG2("\n        face_global()  offset: %ld   count: %d\n",
                           globoff, globcount);

  /* get face global buffer */

#if IF_ROM
    b->p.in.pfgseg = (LPSB8)b->p.in.plibfont + globoff;

#endif    /* IF_ROM */
#if IF_DISK
#if USING_16_BIT_DOS    /* 16 bit platform */
    if(0==(b->p.in.hfgseg = FMalloc_rd(FSA b->fh, globcount, globoff)))
#else
    if(0==(b->p.in.hfgseg = FMalloc_rd(FSA b->fh, (SL32)globcount, globoff))) /* 12-17-92 */
#endif
    {
        IXclose_file(FSA b);
        BUFfree(FSA b->p.in.hface_header_seg);
        return ERR_face_abort;
    }
#endif    /* IF_DISK */

    b->p.in.sfgseg = globcount;

  /*  Fill in sub-segment offsets and sizes. First set all offsets to
   *  MAX_UWORD which means the sub-segment is not present.
   */

    b->p.in.ogif             = MAX_UWORD;
    b->p.in.otrack_kern_seg  = MAX_UWORD;
    b->p.in.otext_kern_seg   = MAX_UWORD;
    b->p.in.odesign_kern_seg = MAX_UWORD;
    b->p.in.owidth_seg       = MAX_UWORD;
    b->p.in.oattribute       = MAX_UWORD;
    b->p.in.orast            = MAX_UWORD;
    b->p.in.otf_header_seg   = MAX_UWORD;
    b->p.in.ocompound_seg    = MAX_UWORD;
    b->p.in.odisplay         = MAX_UWORD;
    b->p.in.ofont_alias_seg  = MAX_UWORD;
    b->p.in.ocopy            = MAX_UWORD;

  /*  Read segment directory and set sub-segment offsets and sizes */

    p = fgseg(FSA b);

#ifdef AGFADEBUG
    type = *((LPUW16)p);
#endif
    p += sizeof( UW16 );
#ifdef AGFADEBUG
#if (NAT_ALIGN >= 4 )       /* 08-31-01 dz */
    MAKELONG(size, p);
#else
    size = *((LPUL32)p);
#endif 
#endif  /* AGFADEBUG */
    p += sizeof( UL32 );

//    DBG2("            type = %d    size = %ld\n",type, size);

    DBG("\n            directory\n");
    do
    {
        key =   *((LPUW16)p);     p += sizeof( UW16 );

#if (NAT_ALIGN >= 4 )       /* 08-31-01 dz */
        MAKELONG( off, p );       p += sizeof( UL32 );
#else
        off =   *((LPUL32)p);     p += sizeof( UL32 );
#endif 

        count = *((LPUW16)p);     p += sizeof( UW16 );
        DBG3("            key / offset / count  %d   %ld   %d\n",
                                              key,off,count);

        oseg   = (UW16)(off + 6);
        count -= 6;
        switch (key)
        {
            case 100:  b->p.in.ogif = oseg - 6;          /* Intellifont        */
                       b->p.in.gifct = count + 6;
                       break;
            case 101:  b->p.in.otrack_kern_seg = oseg;   /* track kerning      */
                       b->p.in.strack_kern_seg = count;
                       break;
            case 102:  b->p.in.otext_kern_seg = oseg;    /* text kerning       */
                       b->p.in.stext_kern_seg = count;
                       break;
            case 103:  b->p.in.odesign_kern_seg = oseg;  /* designer kerning   */
                       b->p.in.sdesign_kern_seg = count;
                       break;
            case 104:  b->p.in.owidth_seg = oseg;        /* character widths   */
                       b->p.in.swidth_seg = count;
                       break;
            case 105:  b->p.in.oattribute = oseg;        /* attribute hdr      */
                       b->p.in.sattribute = count;
                       break;
            case 106:  b->p.in.orast = oseg;             /* raster parameter    */
                       b->p.in.srast = count;
                       break;
            case 107:  b->p.in.otf_header_seg = oseg;    /* typeface header     */
                       b->p.in.stf_header_seg = count;
                       break;
            case 108:  b->p.in.ocompound_seg = oseg;     /* compound characters */
                       b->p.in.scompound_seg = count;
                       break;
            case 109:  b->p.in.odisplay = oseg;          /* display header      */
                       b->p.in.sdisplay = count;
                       break;
            case 110:  b->p.in.ofont_alias_seg = oseg;   /* font alias          */
                       b->p.in.sfont_alias_seg = count;
                       break;
            case 111:  b->p.in.ocopy = oseg - 6;         /* Copyright segment   */
                       b->p.in.scopy = count + 6;
                       break;
            default:   break;
        }
    }
    while (key != (UW16)-1);              /* added cast  -ss 6/21/91  */

    return maybe_cleanup_files(FSA b, SUCCESS);
}

/*-------------------*/
/*  ifset_char       */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  ifset_char (FSP PBUCKET pb, UL32 chId) 
#else
GLOBAL UW16
ifset_char (pb, chId)
    PBUCKET  pb;
    UL32    chId;
#endif
{
   DBG ("\nifset_char()\n");
   pb=pb;chId=chId;/*nop*/
   return SUCCESS;
}


/*-------------------*/
/*     LIBmake_cd    */
/*-------------------*/
#if defined (ANSI_DEFS)
GLOBAL UW16  LIBmake_cd(FSP PBUCKET bucket, UW16 chId, PCHR_DEF chr_def,
    SL32 buck_search_lvl)
#else
GLOBAL UW16
LIBmake_cd(bucket, chId, chr_def, buck_search_lvl)
    PBUCKET  bucket;
    UW16    chId;
    PCHR_DEF chr_def;
    SL32      buck_search_lvl;
#endif
{
    SW16         m;
    UW16        j;  /* change SW16 to UW16 - 2/5/92 - rs */
    LPSB8        p;
    UW16        num_cc;    /* number of cc defs */
    UW16        cc_cgnum;
    UW16        cgnum;
    PCHR_DEF     cd;
#if SLIM_FONTS
    PCHARWIDTH   widthPtr;
#endif

    DBG1("LIBmake_cd(chId = %d)\n", chId);

#if SLIM_FONTS
    if_state.missing_ccpart_widthinfo.flags = 0;
    if_state.missing_ccpart_widthinfo.width = 0;
    if_state.missing_ccparts = 0;
#endif

    if (FC_NO_SSMAP(&if_state.fcCur))
        cgnum = chId;
    else
        cgnum = SYMmap(FSA chId, FC_IF_TYPE);

    if((chr_def->index = FMchar_index(FSA bucket, cgnum)) >= 0)
    {
        DBG("    found as primary\n");
        if_state.chr_def_hdr.is_compound = FALSE;
        if_state.chr_def_hdr.num_parts   = 1;
#if SLIM_FONTS
        if_state.chr_def_hdr.mirror_flags = (UB8)0;
#endif
        chr_def->cgnum    = cgnum;
        chr_def->buck_search_lvl = buck_search_lvl;
        chr_def->offset.x = 0;
        chr_def->offset.y = 0;
        return SUCCESS;
    }
    /*  Assume have a compound char  */
        DBG("    searching compound\n");

        if_state.chr_def_hdr.is_compound = TRUE;
        if(bucket->p.in.ocompound_seg == MAX_UWORD)
           return ERR_find_cgnum;
        p = fgseg(FSA bucket) + bucket->p.in.ocompound_seg;

        num_cc = *(LPUW16)p;    p += sizeof( UW16 );
        DBG1("    num_cc %d\n", num_cc);

        for(j=0; j<num_cc; j++)    /* search thru cchar segment  */
        {
            cc_cgnum              = *(LPUW16)p;    p += sizeof( UW16 );
            if_state.chr_def_hdr.escape.x  = *(LPSW16)p;     p += sizeof( SW16 );

            if(!B_U_LIB(bucket))      /* v_esc not in U libraries  */
            {
               if_state.chr_def_hdr.escape.y = *(LPSW16)p;
               p += sizeof( SW16 );
            }
            else
               if_state.chr_def_hdr.escape.y = 0;

                                      /* mirror flags in num_parts */
            if_state.chr_def_hdr.num_parts = *(LPSW16)p;
            p += sizeof( SW16 );

#if SLIM_FONTS
                             /*  Have mirror flags        -ss 6/4/91     */
            if( if_state.chr_def_hdr.num_parts & MIRROR_MASK )
            {
               if_state.chr_def_hdr.mirror_flags
                           = (UB8)MIRROR_FLAGS(if_state.chr_def_hdr.num_parts);
               if_state.chr_def_hdr.num_parts   &= NPARTS_MASK;
            }
            else if_state.chr_def_hdr.mirror_flags = (UB8)0;
#endif  /*  SLIM_FONTS  */


            if(cc_cgnum != cgnum)
            {  /* skip over 3 words for each part: cgnum, offset.x, .y */
               p += if_state.chr_def_hdr.num_parts * 3 * sizeof( SW16 );
               continue;     /* go to examine next cchar in segment */
            }

          /*  Protect against over-running chr_def array. This means
           *  we won't process characters in a font that contains
           *  compound characters with too many parts even if these
           *  complex compound characters are never used.
           */

           if(if_state.chr_def_hdr.num_parts > MAX_CC_PARTS)
               return ERR_cc_complex;

            /*  Have the compound character. */

            DBG4("    cgnum %d  escape (%d, %d)    num_parts %d\n",
                              cgnum, if_state.chr_def_hdr.escape.x, 
                              if_state.chr_def_hdr.escape.y, if_state.chr_def_hdr.num_parts);

           /*  For each compound character part, fill in its
            *  cgnum, offsets, bucket number and character index.
            */

            cd = chr_def;

            for(m=0; m<if_state.chr_def_hdr.num_parts; m++)
            {
                    DBG3("        cgnum%d   xoffset %d yoffset %d\n",
                                  cd->cgnum, cd->offset.x, cd->offset.y);

                    cd->cgnum     = *(LPUW16)p;
                    p += sizeof( UW16 );

                    cd->offset.x  = *(LPSW16)p;
                    p += sizeof( SW16 );

                    cd->offset.y  = *(LPSW16)p;
                    p += sizeof( SW16 );
                    
#if SLIM_FONTS
                   /* compensate for positive offset expected to be negative*/
                    if( if_state.chr_def_hdr.mirror_flags )
                    {
                       if( if_state.chr_def_hdr.mirror_flags & MIRROR_X_MASK )
                          cd->offset.x = -cd->offset.x;
                       if( if_state.chr_def_hdr.mirror_flags & MIRROR_Y_MASK )
                          cd->offset.y = -cd->offset.y;
                       /*** fill this in when have data to test ***
                       if( if_state.chr_def_hdr.mirror_flags & MIRROR_ROT90_MASK )
                         ???;
                       ********************************************/
                    }
#endif  /*  SLIM_FONTS  */

                    cd->buck_search_lvl = buck_search_lvl;
                    if((cd->index = FMchar_index(FSA bucket, cd->cgnum)) < 0)
#if SLIM_FONTS
                    {
                        if_state.missing_ccparts = 1;
                                         /* setup to search at next level */
                        cd->buck_search_lvl++;
                    }
#else
                        return ERR_no_cc_part;
#endif
                    cd++;
            }

#if SLIM_FONTS
          if( if_state.missing_ccparts )
            break;
          else
#endif
            return SUCCESS;

        }   /* for each entry in cc segment */

#if FCO_RDR && SLIM_FONTS
       if (if_state.missing_ccparts)
          return ERR_no_cc_part;
       else
       {
          chr_def[0].cgnum = 0xFFFF; /* flags indicating this is not an ext cc */
          chr_def[0].index = -1; 
       }
#endif

#if SLIM_FONTS
        /*  Special processing for External Compound Characters  */
        if( if_state.missing_ccparts )
        {
           cd = chr_def;
           /* Bump cd - fix for not finding all correct parts -ss 6/18/91 */
           for( m = 0; m < if_state.chr_def_hdr.num_parts; m++, cd++ )
           {
              if( cd->index >= 0 )    /* have a part all filled in  */
                continue;

              /* search down bucket tree til find the character     */
              while( cd->buck_search_lvl < if_state.fontindex.num_searches )   
              {
                 if( if_state.fontindex.icur_index[cd->buck_search_lvl-1] == MAX_UWORD)
                    return ERR_no_cc_part; /* no more valid buckets */

                 if( BUCKfind( FSA cd->buck_search_lvl, CREATE_BUCKET, &bucket )
                                                                 != SUCCESS )
                    return ERR_no_cc_part;       /* no more buckets */
   
                 if((cd->index = FMchar_index(FSA bucket, cd->cgnum)) >= 0)
                 {
                    if (bucket->p.in.owidth_seg != MAX_UWORD)
                    {
                        widthPtr = ((PCHARWIDTH)(fgseg(FSA bucket) + 
                           bucket->p.in.owidth_seg) + cd->index);
                        if_state.missing_ccpart_widthinfo.flags = widthPtr->flags;
                        if_state.missing_ccpart_widthinfo.width = widthPtr->width;
                    }
                    break;                          /*  found it   */
                 }

                 cd->buck_search_lvl++;    /* setup to search at next level */
              }  /*  end - while  */

              /* 21-Aug-92 - rs
                 add fix for case where we have a non-Intellifont primary
                 font which does not contain the desired character and the
                 character ends up being a compound char with a part in the
                 universals (ie PB symbol set, chId 82 - Rx prescription).
             */
              if(cd->buck_search_lvl >= if_state.fontindex.num_searches)
                return ERR_no_cc_part;
                
           }  /*  end - m loop  */
  
           /* restore current bucket context  */
           BUCKfind( FSA buck_search_lvl, CREATE_BUCKET, &bucket );
           return SUCCESS;                     /* added  -ss 10/25/91 */
        }  /*  fill in missing cc parts  */
#endif  /*  SLIM_FONTS  */

#if SLIM_FONTS
   if_state.chr_def_hdr.mirror_flags = (UB8)0;   /* 10-08-93 - mby */
#endif
   return (UW16)FAILURE;            /* added  -ss 10/25/91 */

}  /*  end - LIBmake_cd  */


/*-------------------*/
/*  FMchar_index    */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL SW16  FMchar_index(FSP PBUCKET b, UW16 cgnum)
#else
MLOCAL SW16
FMchar_index(b, cgnum)
    PBUCKET  b;
    UW16    cgnum;
#endif
{
    LPSB8    chptr;
    UW16    dir_entry_size;
    SW16     i,lo,hi;
    UW16    charnum;

  /* find entry in character directory */

    DBG1("        FMchar_index(%d)\n", cgnum);

    /* use defines set in segments.h for correct size on SPARC -ss 8/28/91 */
    if(B_U_LIB(b))
       dir_entry_size = US_CH_DIR_ENTRY_SIZE;
    else 
       dir_entry_size = CH_DIR_ENTRY_SIZE;

    chptr = char_dir(FSA b);
    lo = 0;
    hi = (SW16)b->p.in.ch_count - 1;
    while(lo <= hi)
    {
        i = (lo + hi)/2;
        charnum = *(LPUW16)(chptr + i*dir_entry_size);
        if(charnum  == cgnum)
        {
            DBG1("            index = %d\n", i);
            return i;
        }
        else if(charnum < cgnum) lo = i+1;
        else hi = i-1;
    }
    DBG("            character not found\n");
    return -1;
}


/*-------------------*/
/*    rd_char        */
/*-------------------*/
#if defined (ANSI_DEFS)
MLOCAL UW16  rd_char(FSP PCHR_DEF cd)
#else
MLOCAL UW16
rd_char(cd)
    PCHR_DEF cd;
#endif
{
    UW16             status;
    PBUCKET           b;
    UL32             charoff;
    UW16             charcount;   /*  size of character in bytes  */
#if (BYTEORDER == HILO || (NAT_ALIGN >=4 && BYTEORDER == LOHI)) /* Motorola format, don't swap bytes */
    UW16    hiword, loword;                                      /* 08-31-01 dz */
#endif
#if (NAT_ALIGN >= 4)
    LPSB8             p;
    SL32               tmpi;
#endif

    DBG2("        rd_char(buck_search_lvl = %ld, index = index = %d)\n",
                                      cd->buck_search_lvl, cd->index);

  /* Find and open typeface file */

    status = BUCKfind(FSA cd->buck_search_lvl, CREATE_BUCKET, &b);
    if (status)
        return status;


  /* Initialize typeface global data if need be */

    if(!if_init_glob(FSA b))
        return maybe_cleanup_files(FSA b, ERR_if_init_glob);

    /* handle the IF_PCLEOI case first */
#if PCLEO_RDR
    if( b->extern_font )
    {

        if_state.expand_buf  = (LPSB8)MEMptr( if_state.hchar_buf );
#if ROM
        if_state.expand_size = EXPBUFSIZE;
#endif
#if DISK_FONTS
        if_state.expand_size = CHARBUFSIZE;     /* have the whole thing, use it   */
#endif
#if (NAT_ALIGN >= 4)
        /* make sure expand_buf is long aligned before starting -ss 10/9/91 */
        if( tmpi = ((SL32)if_state.expand_buf & MEM_ALIGN) )
        {
            if_state.expand_buf  += (MEM_ALIGN+1) - tmpi;
            if_state.expand_size -= (MEM_ALIGN+1) - tmpi;
        }
#endif  /* (NAT_ALIGN >= 4) */

        if_state.char_buf    = (LPSB8)cd->pgif;
        return if_init_char(FSA0);
    }
#endif /* PCLEO_RDR */

/*  ASSERT: at this point we have a ROM or DISK Library File */


  /* Get offset to character and size of character */

#if (NAT_ALIGN >= 4 && BYTEORDER == HILO) 

    if(B_U_LIB(b))    /* Ultra-slim fonts have a different char directory */
    {
       p  = char_dir(FSA b)                       /* beginning of entries     */
         + (cd->index * US_CH_DIR_ENTRY_SIZE) /* our entry                */
         + sizeof( UW16) ;                   /* skip charnum to charoff  */
       MAKELONG( charoff, p );              /* added line -ss 3/31/92 */
       p += US_CH_DIR_ENTRY_SIZE;             /* charoff in next entry     */
       MAKELONG( tmpi, p );                   /* grab charoff              */
       charcount = tmpi - charoff;   /* diff from next char offset to orig */
    }
    else
   {   /* changed to rely on charcount directly out of struct -ss 3/24/92 */
       p  = char_dir(FSA b)                      /* beginning of entries      */
         + (cd->index * CH_DIR_ENTRY_SIZE)   /* our entry                 */
         + sizeof( UW16) ;                  /* skip charnum to charoff   */
       MAKELONG( charoff, p );               /* grab charoff              */
       charcount = *(LPUW16)(p + sizeof(UL32) );
    }

#elif (NAT_ALIGN == 4 && BYTEORDER == LOHI)   /* changed from "ifdef SPARC" - jfd 9/30/92 */
    if(B_U_LIB(b))    /* Ultra-slim fonts have a different char directory */
    {
       p  = char_dir(FSA b)                       /* beginning of entries     */
         + (cd->index * US_CH_DIR_ENTRY_SIZE) /* our entry                */
         + sizeof( UW16) ;                   /* skip charnum to charoff  */
       MAKELONG( charoff, p );                 /* 08-31-01 dz */
       DBG1(" charoff = %ld", charoff);
       p += US_CH_DIR_ENTRY_SIZE;             /* charoff in next entry     */
       MAKELONG( tmpi, p );                   /* 08-31-01 dz */
       DBG1(" tmpi = %ld", tmpi);
       charcount = tmpi - charoff;   /* diff from next char offset to orig */
       DBG1(" charcount = %d", charcount);
    }
    else
   {   /* changed to rely on charcount directly out of struct -ss 3/24/92 */
       p  = char_dir(FSA b)                      /* beginning of entries      */
         + (cd->index * CH_DIR_ENTRY_SIZE)   /* our entry                 */
         + sizeof( UW16) ;                  /* skip charnum to charoff   */
       MAKELONG( charoff, p );             /* 08-31-01 dz */
       DBG1(" charoff = %ld", charoff);
       charcount = *(LPUW16)(p + sizeof(UL32) );
       DBG1(" charcount = %d", charcount);
    }
#elif (NAT_ALIGN == 8 && BYTEORDER == LOHI) 
/*** cloned from previous case: should work unless there's any explicit alignment ***/
    if(B_U_LIB(b))    /* Ultra-slim fonts have a different char directory */
    {
       p  = char_dir(FSA b)                       /* beginning of entries     */
         + (cd->index * US_CH_DIR_ENTRY_SIZE) /* our entry                */
         + sizeof( UW16) ;                   /* skip charnum to charoff  */
       MAKELONG( charoff, p );             /* 08-31-01 dz */
       DBG1(" charoff = %ld", charoff);
       p += US_CH_DIR_ENTRY_SIZE;             /* charoff in next entry     */
       MAKELONG( tmpi, p );                   /* 08-31-01 dz */
       DBG1(" tmpi = %ld", tmpi);
       charcount = tmpi - charoff;   /* diff from next char offset to orig */
       DBG1(" charcount = %d", charcount);
    }
    else
   {   /* changed to rely on charcount directly out of struct -ss 3/24/92 */
       p  = char_dir(FSA b)                      /* beginning of entries      */
         + (cd->index * CH_DIR_ENTRY_SIZE)   /* our entry                 */
         + sizeof( UW16) ;                  /* skip charnum to charoff   */
       MAKELONG( charoff, p );              /* 08-31-01 dz */
       DBG1(" charoff = %ld", charoff);
       charcount = *(LPUW16)(p + sizeof(UL32) );
       DBG1(" charcount = %d", charcount);
    }
#else

    if(B_U_LIB(b))  /* Ultra-slim fonts have a different char directory */
    {
        PUS_CH_DIR_ENTRY  uschptr;

        uschptr   = (PUS_CH_DIR_ENTRY)char_dir(FSA b) + cd->index;
        charoff   = uschptr->charoff;
        charcount = (UW16)((uschptr+1)->charoff - uschptr->charoff);
    }
    else            /* normal character directory structure */
    {
        PCH_DIR_ENTRY     chptr;

        chptr     = (PCH_DIR_ENTRY)char_dir(FSA b) + cd->index;
        charoff   = chptr->charoff;
        charcount = chptr->charcount;
    }
#endif  /* NAT_ALIGN,BYTEORDER */

  /*  Get pointer to character */

#if IF_ROM
    if_state.char_buf    = (LPSB8)b->p.in.plibfont + charoff;
    if_state.expand_buf  = (LPSB8)MEMptr( if_state.hchar_buf );
    if_state.expand_size = EXPBUFSIZE;
#endif    /* IF_ROM */
#if IF_DISK
    if_state.char_buf = (LPSB8)MEMptr(if_state.hchar_buf);
    if_state.expand_buf = if_state.char_buf + charcount; /* unused char buffer after data */
    if_state.expand_size = CHARBUFSIZE - charcount;

#if (NAT_ALIGN == 4) || (NAT_ALIGN == 8)
    /* make sure expand_buf is long aligned before starting -ss 10/9/91 */
    if( tmpi = ((SL32)if_state.expand_buf & 0x03) )
    {
       if_state.expand_buf  += 4 - tmpi;
       if_state.expand_size -= 4 - tmpi;
    }
#endif  /* (NAT_ALIGN == 4) || (NAT_ALIGN == 8) */


    if(charcount > CHARBUFSIZE)
        return maybe_cleanup_files(FSA b, ERR_ov_char_buf);

#if USING_16_BIT_DOS        /* 16 bit platform */
    if(!FMseek_read(FSA b->fh, (SL32)charoff, (UW16)charcount, if_state.char_buf))
#else /* 32 bit platform */
    if(!FMseek_read(FSA b->fh, (SL32)charoff, (SL32)charcount, if_state.char_buf))
#endif
        return maybe_cleanup_files(FSA b, ERR_rd_char_data);

    maybe_cleanup_files(FSA b, SUCCESS);

#endif  /* IF_DISK */

  /*  Initialize character data structures  */
    return if_init_char(FSA0);
}

/*-------------------*/
/*  DArd_char        */
/*-------------------*/
/*  Find character with cgnum = n, allocate a character buffer, read the
 *  character data into the buffer, and initialize character data structures.
 *  The function rd_char() above does all of the work. This function
 *  tries to substitute characters from an auxilary library if the character
 *  being processed is in hq2 format.
 */
#if defined (ANSI_DEFS)
GLOBAL UW16  DArd_char(FSP PCHR_DEF cd)
#else
GLOBAL UW16
DArd_char(cd)
    PCHR_DEF cd;
#endif
{
    UW16       status;
#if PCLEO_RDR  || (IF_PCLEOI && IF_ROM)
    FONTINDEX  fi_sav;
#endif
    FONTCONTEXT tmp_fc;
    PBUCKET     b;
    CHR_DEF     tmpcd;

#if (IF_PCLEOI && IF_ROM)
    SL32 i;
#endif  /* (IF_PCLEOI && IF_ROM) */

    DBG1("        DArd_char(cgnum = %d)\n", cd->cgnum);

    status = rd_char(FSA cd);
    if (status)
    {
      /* If we failed because the character was not hq3 format, then try
       * to find the character in the substitute hq3 libraries.
       */

                                                 /* added cast  -ss 10/17/91 */
        if(status != (UW16)ERR_not_hq3) return status;  /* some other error */


      /*  Set the three bucket index entries, the primary TF_SENSITIVE
       *  bucket entry will contain our typeface. The update typeface
       *  number is negative so that FMfont_change() won't get confused
       *  when we go back to processing normal typefaces. This way he
       *  won't think that a BUCKET already has normal typeface header
       *  info loaded when in fact it has update typeface header info.
       */

        if (!cd->buck_search_lvl)
           tmp_fc.font_id = - (if_state.fontindex.cur_tf_num); /* at TFS level */
        else
           tmp_fc.font_id = - (if_state.fontindex.pix->tfnum); /* at plugin level */

       /* Initialization for BUCKfind; jwd, 9-16-97 */

        tmp_fc.ssnum    = if_state.fontindex.cur_ssnum;
        tmp_fc.font_hdr = (LPUB8 )0;

        DBG1("    update_tfnum = %ld\n", tmp_fc.font_id);
#if PCLEO_RDR  || (IF_PCLEOI && IF_ROM)
        fi_sav = if_state.fontindex;    /* save old font index */
#endif

#if IF_DISK || ((DISK_FONTS && !ROM) && IF_PCLEOI)   /* jwd, 08/16/01 */
      /* Read in the font index for the substitute libraries */
        status = IXmak_font_index(FSA "hq3.fnt");
        if (status)
            return ERR_not_hq3;
        tmp_fc.format = 0;
#else
        tmp_fc.format = FC_ROM_TYPE;
#endif  /* IF_DISK */

                                /* Conflict between ASIAN_ENCODING and HQ2 */
       tmp_fc.ExtndFlags = 0 ;  /* handling fix.    6-26-97   jqz          */
                                /* reported by Pacific SemiConductor       */

#if (IF_PCLEOI && IF_ROM)

      /* Special HQ2 processing optimization used for rom pcleos:
       *
       * (1) Search HQ3 substitute library
       * (2) Search resident fonts
       *
       */

     for (i=0; i<2; i++)
     {
#endif  /* (IF_PCLEOI && IF_ROM) */

        if(!(status = IXget_fnt_index(FSA &tmp_fc)))
        {

            if(!(status = BUCKfind(FSA TF_SENSITIVE, CREATE_BUCKET, &b)))
            {
#if PCLEO_RDR
                tmpcd.pgif = (LPUB8)NULL;

                /*  For pcleo, the cd->cgnum is really the ascii code */
              /*  Convert to cgnum for use with HQ2->HQ3 libs       */

#if (IF_PCLEOI && IF_ROM)

              /*  NOTE: If we are processing one part of a compound
               *        character, there is no need to call SYMmap().
               */

              if ( (fi_sav.font_type & FC_EXTERN_TYPE) && !if_state.chr_def_hdr.is_compound)
#else
              if( fi_sav.font_type & FC_EXTERN_TYPE)
#endif  /* (IF_PCLEOI && IF_ROM) */
              {
                
                if (FC_NO_SSMAP(&if_state.fcCur))
              {
                 tmpcd.cgnum = cd->cgnum;  /* 3-21-95 jfd */
              }
              else
              {
                 SW16 MSL_index = -1;

                 if (if_state.fcCur.ssnum == DL_SYMSET)
                 {
                     if ( (MSL_index = MSL_to_CG_index(FSA cd->cgnum)) == -1)
                         tmpcd.cgnum = 0;
                     else
                         tmpcd.cgnum = CG_nums[MSL_index];
                 }
                 else
                     tmpcd.cgnum = SYMmap(FSA cd->cgnum, FC_IF_TYPE);

              }    /* FC_NO_SSMAP */

                 if (!tmpcd.cgnum)
                 {
                    if_state.fontindex = fi_sav;    /* restore font index    */
                    return ERR_no_cgnum;
                 }
              }
              else
#endif  /* PCLEO_RDR */
                tmpcd.cgnum = cd->cgnum;

                if((tmpcd.index = FMchar_index(FSA b, tmpcd.cgnum)) >= 0)
                {
                    tmpcd.buck_search_lvl = TF_SENSITIVE;
                    status = rd_char(FSA &tmpcd);
                }
#if (IF_PCLEOI && IF_ROM)
                else if (fi_sav.font_type & FC_EXTERN_TYPE)
                {

                /* Might be compound character. Have to check for
                 * possibility.
                 */

                   if ((status = LIBmake_cd(FSA b, cd->cgnum, if_state.chr_def,
                          (SL32)TF_SENSITIVE)) != 0)
                   {
                      if_state.fontindex = fi_sav;    /* restore font index    */
                      return status;
                   }

                   tmpcd.cgnum = cd->cgnum;
                   tmpcd.index = cd->index;
                   tmpcd.buck_search_lvl = TF_SENSITIVE;
                   status = rd_char(FSA &tmpcd);

                }  /* end else */
#endif  /* (IF_PCLEOI && IF_ROM) */
                else
                    status = ERR_not_hq3;
            }
        }

#if IF_DISK
        BUFfree(FSA if_state.fontindex.hfnt_index);   /* free temp. font index */
#endif

#if (IF_PCLEOI && IF_ROM)

       /* If character was not found in HQ3 substitute libraries,
        * restore typeface number and search resident fonts
        * if TFS is pcleo and ROM is enabled.
        */

        if(!status)
           break;

        else if (if_state.fontindex.font_type & FC_EXTERN_TYPE)
           tmp_fc.font_id = fi_sav.cur_tf_num; /* at TFS level */

     }  /* end for */

#endif  /* (IF_PCLEOI && IF_ROM) */
        if(status) return ERR_not_hq3;
    }

    return SUCCESS;
}


#if DYNAMIC_FONTS

#define  FONTALIASNAME "HP                  "
#define  FAT_NFATS     6
#define  FAT_FIRSTTAB  8
#define  FAT_TFNUM     100
#define  FAT_XREFSIZE  104
#define  FAT_SIMPLESERIF 31
#define  FAT_WEIGHT    19
#define  FAT_POSTURE   17
#define  FAC_FIXEDPITCH 8
#define  FAC_SPACEBAND 64


#ifndef FM_PF_OPTIMIZE
#if (BYTEORDER == HILO) /* Motorola format, don't swap bytes. */
#define GETWORD_NS(p)  \
           ( ( ((UW16) *((LPUB8)(p))) << 8 ) | (UW16) *((LPUB8)(p)+1) )
#define GETLONG_NS(p)  \
           ( ( ((UL32) *((LPUB8)(p))) << 24)   |  \
             ( ((UL32) *((LPUB8)(p)+1)) << 16) |  \
             ( ((UL32) *((LPUB8)(p)+2)) << 8)  |  \
               (UL32) *((LPUB8)(p)+3)             \
           )

#else                   /* Intel format, do swap bytes. */
#define GETWORD_NS(p) \
           ( (UW16) *((LPUB8)(p)) | ( ((UW16) *((LPUB8)(p)+1)) << 8 ) )
#define GETLONG_NS(p)  \
           ( ( ((UL32) *((LPUB8)(p)+3)) << 24)   |  \
             ( ((UL32) *((LPUB8)(p)+2)) << 16) |    \
             ( ((UL32) *((LPUB8)(p)+1)) << 8)  |    \
               (UL32) *((LPUB8)(p))                 \
           )
#endif

#else
#define GETWORD_NS(p) ( *((LPUW16)(p)) )   /* most efficient - if CPU can */
#define GETLONG_NS(p) ( *((LPUL32)(p)) )   /* tolerate any byte alignment */
#endif

#if defined (ANSI_DEFS)
MLOCAL UW16 FMprocess_face( FSP LPUB8 fontPtr, PBUCKET pBk )

#else
MLOCAL UW16 FMprocess_face( fontPtr, pBk )
   LPUB8 fontPtr;
   PBUCKET pBk;
#endif  /* !defined (ANSI_DEFS) */

{
#if DISK_FONTS
    UB8   buffer[10];
#endif
    LPUB8 pbuf;
    SW16  bucket_num;
    UW16  lib_type;
    UW16  fcount;
    UL32  offset;
    UW16  key;

#if DISK_FONTS
    if (pBk->has_path)
    {
        UW16 status =
               IXopen_file(FSA (PINDEX_ENTRY)0, pBk); /* pathname is in bucket */
        if (status) return status;
    }
    if_state.fontindex.dynix.bucket_num = 0;
    pbuf = buffer;
#else
    if_state.fontindex.dynix.bucket_num = ROM_TYPE;
#endif
    /* First word must be 'D', 'S', or 'U' */
    /* ks - 15/02/99 added 'V' format support */
#if ROM
    if (!(pbuf = fontPtr + 0L))
#else
    if (!FMseek_read(FSA pBk->fh, 0L, 2, (LPSB8)pbuf))
#endif
    {
        goto IXerror1;
    }
    lib_type = GETWORD_NS(pbuf);
    offset = 2;
    switch (lib_type)
    {
        case 0x0044: if_state.fontindex.dynix.bucket_num |= D_LIB; break;
        case 0x0053: if_state.fontindex.dynix.bucket_num |= S_LIB; break;
        case 0x0055: if_state.fontindex.dynix.bucket_num |= U_LIB; break;
        
        /* ks - March 15, 2000
           chglib.exe (converts cdi to cdm) has never swapped the 
           first 8 bytes of a 'v' format intellifont font correctly. */ 
        case 0x5600:
        case 0x0056: 
            if_state.fontindex.dynix.bucket_num |= V_LIB; offset = 8; break;
        default:     goto IXerror2;
    }

    /* Read file segment directory until find File Directory Segment,
       keyword = 2. */
    fcount = 0;
    do
    {
#if ROM
        if (!(pbuf = fontPtr + offset))
#else
        if (!FMseek_read(FSA pBk->fh, offset, 8, (LPSB8)pbuf))
#endif
        {
            goto IXerror1;
        }
        key = GETWORD_NS(pbuf);
        if(key == 2)
        {
            offset = GETLONG_NS(pbuf + 2);
            fcount = GETWORD_NS(pbuf + 6);
            break;
        }
        offset += 8;
    } while (key != (UW16)-1);

    if (!fcount)
        goto IXerror2;

    /* Grab first entry in file directory (there should only be one, anyway).
     * Get typeface number, face header offset, face header byte count. */
#if ROM
    if (!(pbuf = fontPtr + offset))
#else
    if (!FMseek_read(FSA pBk->fh, offset, 10, (LPSB8)pbuf))
#endif
    {
        goto IXerror1;
    }
    if ( (if_state.fontindex.dynix.tfnum = GETLONG_NS(pbuf)) == -1)
        goto IXerror2;
    if_state.fontindex.dynix.fhoff = GETLONG_NS(pbuf + 4);
    if_state.fontindex.dynix.fhcount = GETWORD_NS(pbuf + 8);

    if ( !find_bucket_type( FSA pBk, fontPtr,
                            if_state.fontindex.dynix.fhoff, if_state.fontindex.dynix.tfnum,
                            &bucket_num ))
        goto IXerror1;
    if_state.fontindex.dynix.bucket_num |= bucket_num;
#if DISK_FONTS
    if (pBk->has_path)
        IXclose_file(FSA pBk);
#endif
    
    return SUCCESS;

IXerror1:
#if DISK_FONTS
    if (pBk->has_path)
        IXclose_file(FSA pBk);
#endif
    return ERR_if_read_libfile;

IXerror2:
#if DISK_FONTS
    if (pBk->has_path)
        IXclose_file(FSA pBk);
#endif
    return ERR_if_process_face;
}


/************************
 *   find_bucket_type   *
 ************************
 *
 * Returns bucket bits 0-5 (typeface characteristics and fixed pitch plugin
 *   description) as described in ix.h in bucket_num.
 *   bucket_num defaults to 0 (normal-serif-upright, no FP) if global data is
 *   missing from the library file.
 * Returns error (FALSE) if unable to read the library file.
 * bucket->fh is the file handle (disk fonts)
 * fontPtr is the font pointer (ROM fonts)
 * fhoffset is the face header offset in the libr file.
 * tfnum is the Agfa typeface number.
 */
#if defined (ANSI_DEFS)
MLOCAL BOOLEAN   find_bucket_type( FSP PBUCKET bucket, LPUB8 fontPtr,
                                   UL32 fhoffset, SL32 tfnum,
                                   SW16* bucket_num)
#else
MLOCAL BOOLEAN   find_bucket_type( bucket, fontPtr, fhoffset, tfnum, bucket_num )
  PBUCKET bucket;
  LPUB8   fontPtr;
  UL32    fhoffset;
  SL32    tfnum;
  SW16*   bucket_num;
#endif  /* !defined (ANSI_DEFS) */
{
#if DISK_FONTS
    UB8   buffer[8];
    LPUB8 pbuf = buffer;
#else
    LPUB8 pbuf;
#endif
    UW16  key;
    LPSB8 pSegData, pFAT;
    SL32   nfats, nxref, found_table_name;
    SL32   fat_flag=0;
    UL32  gsegOff;
    SL32   ii, iii;
    UL32  offset;
    UL32  seg_off;
#if DISK_FONTS
    MEM_HANDLE  hSeg;
    UW16  seg_size;
#endif
#if CGFIXED_PITCH
    SL32   attr_flag=0;
#endif

    *bucket_num = 0;

#if ROM
    if (!(pbuf = fontPtr + fhoffset))
#else
    if (!FMseek_read(FSA bucket->fh, fhoffset, 4, (LPSB8)pbuf))
#endif
    {
        return FALSE;
    }
    gsegOff = GETLONG_NS(pbuf);    /* offset to TF Global Segment */

    /* loop through each segment of the face header. Look for the
       Attribute Header (fixed pitch only), the Font Alias Table, and
       the Typeface Header.
       -- Apparently the Font Alias table is always present, so for
          more efficiency, let's not look for or process the TF Header.
     */
    offset = gsegOff + 6;
    while (TRUE)
    {
#if ROM
        if (!(pbuf = fontPtr + offset))
#else
        if (!FMseek_read(FSA bucket->fh, offset, 8, (LPSB8)pbuf))
#endif
        {
            return FALSE;
        }
        if ( (key = GETWORD_NS(pbuf)) == 0xFFFF)
            break;      /* there is no more */
        switch (key)
        {
#if CGFIXED_PITCH
            case ATTRIBUTE_KEY:
                attr_flag = 1;
                seg_off = GETLONG_NS(pbuf+2);
#if DISK_FONTS
                seg_size = GETWORD_NS(pbuf+6);
                hSeg = FMalloc_rd(FSA bucket->fh, seg_size, (gsegOff + seg_off));
                if (hSeg == NIL_MH)
                    break;
                pSegData = (LPSB8)MEMptr(hSeg);
#else
                pSegData = (LPSB8)fontPtr + (gsegOff + seg_off);
#endif
                if (pSegData[FAC_FIXEDPITCH])
                {
                    switch ( GETWORD_NS(pSegData + FAC_SPACEBAND) )
                    {
                      case COURIER_WIDTH:
                        *bucket_num |= B_COURIER;
                        break;
                      case LETTER_GOTHIC_WIDTH:
                        *bucket_num |= B_LETTER_GOTHIC;
                        break;
                      default:    /* fixed pitch, no plugins */
                        *bucket_num |= B_FIXED_PITCH;
                        break;
                    }
                }
#if DISK_FONTS
                BUFfree(FSA hSeg);
#endif
                break;
#endif  /* CGFIXED_PITCH */

            case FONT_ALIAS_KEY:    /* the preferred table */
                seg_off = GETLONG_NS(pbuf+2);
#if DISK_FONTS
                seg_size = GETWORD_NS(pbuf+6);
                hSeg = FMalloc_rd(FSA bucket->fh, seg_size, (gsegOff + seg_off));
                if (hSeg == NIL_MH)
                  break;
                pSegData = (LPSB8)MEMptr(hSeg);
#else
                pSegData = (LPSB8)fontPtr + (gsegOff + seg_off);
#endif
                nfats = GETWORD_NS(pSegData + FAT_NFATS);
                pFAT = pSegData + FAT_FIRSTTAB;
                for (ii=0; ii < nfats; ii++)
                {
                    found_table_name = (STRNCMP(FONTALIASNAME, pFAT, 20) == 0);
                    pFAT += 20;
                    nxref = GETWORD_NS(pFAT);
                    pFAT += 2;
                    for (iii=0; iii < nxref; iii++)
                    {
                        if (found_table_name  &&
                            (UL32)tfnum == GETLONG_NS(pFAT + FAT_TFNUM) )
                        {
                            fat_flag = 1;
                            break;
                        }
                        pFAT += FAT_XREFSIZE;
                    }
                    if (fat_flag)
                        break;
                }
                if (!(pFAT[FAT_SIMPLESERIF] - '0'))
                    *bucket_num |= B_SANS_SERIF;
                if (atoi(pFAT + FAT_WEIGHT) >= 10)
                    *bucket_num |= B_BOLD;
                if (pFAT[FAT_POSTURE] - '0')
                    *bucket_num |= B_ITALIC;
#if DISK_FONTS
                BUFfree(FSA hSeg);
#endif
                break;

            default:   break;

        }   /* switch (key) */

#if CGFIXED_PITCH
        if (fat_flag && attr_flag)
#else
        if (fat_flag)
#endif
            break;              /* exit loop once we've found our tables */
        offset += 8;
    } /* loop through segments in typeface global data */

    return TRUE;
}

#endif  /* DYNAMIC_FONTS */


#if FONTBBOX

/* ifget_FontBBox
 *
 * Returns font bbox and design resolution. Offsets bbox coordinates by
 * the left reference and baseline position.
 */

#define DISPLAY_FONTLIM  14
#define DISPLAY_LEFTREF  30
#define FACEATT_SCALEFC  4

#if defined (ANSI_DEFS)
GLOBAL UW16 ifget_FontBBox( FSP PBUCKET pBucket, BBoxRes* basefont )
#else
GLOBAL UW16 ifget_FontBBox(pBucket, basefont)
  PBUCKET pBucket;
  BBoxRes* basefont;
#endif /* ANSI_DEFS */
{
#if (IF_DISK || IF_ROM) 
    LPSB8    gsegptr;       /* pointer to IF segment data */
    LPSB8    segptr;
    LPUW16   limits;        /* font limits, L R T B       */
    LPUW16   pRef;          /* pointer to IF composition origin coords. */
    LPSB8    orastptr;      /* ptr to raster params */
#endif
#if IF_PCLEOI
    PHPFH pcleoHdr;
#endif

    switch (pBucket->extern_font)
    {
#if (IF_DISK || IF_ROM)
        case 0:
            if (pBucket->p.in.sdisplay  &&  pBucket->p.in.sattribute)
            {
                gsegptr = fgseg(FSA pBucket);
                segptr = gsegptr + pBucket->p.in.odisplay;

                /* Capture "OR" threshold value while we're here */
                /* (11-07-96 JFD */
                if (pBucket->p.in.orast)
                {
                   orastptr = gsegptr + pBucket->p.in.orast;
                   if_state.orThreshold = *(LPUW16)(orastptr);
                }
                else
                   if_state.orThreshold = 0;

                limits = (LPUW16)(segptr + DISPLAY_FONTLIM);
                pRef = (LPUW16)(segptr + DISPLAY_LEFTREF);
                basefont->BBox[0] = limits[1] - *pRef;      /* xmin */
                basefont->BBox[2] = limits[0] - *pRef++;    /* xmax */
                basefont->BBox[1] = limits[3] - *pRef;      /* ymin */
                basefont->BBox[3] = limits[2] - *pRef;      /* ymax */
                segptr = gsegptr + pBucket->p.in.oattribute;
                pRef = (LPUW16)(segptr + FACEATT_SCALEFC);
                basefont->emRes = *pRef;
            }
            else
                return ERRfont_bbox;
            break;
#endif  /* (IF_DISK || IF_ROM) */
#if IF_PCLEOI
        case 1:
            pcleoHdr = (PHPFH)pBucket->cur_font_hdr;
            basefont->BBox[2] = (SL32)pcleoHdr->cellWidth;   /* xmax */
            basefont->BBox[3] = (SL32)pcleoHdr->cellHeight;  /* ymax */
            basefont->BBox[0] = (SL32)pcleoHdr->textWidth;   /* xmin */
            basefont->BBox[1] = (SL32)pcleoHdr->textHeight;  /* ymin */
            basefont->emRes = (SL32)pcleoHdr->scaleFactor;

            /* 11-07-96 JFD */
            if_state.orThreshold = pcleoHdr->orThreshold;   /* OR thresh */

            break;
#endif  /* IF_PCLEOI */
        default:
            return ERRfont_bbox;
    }
    return SUCCESS;
}
#undef DISPLAY_FONTLIM
#undef DISPLAY_LEFTREF
#undef FACEATT_SCALEFC

#endif  /* FONTBBOX */
#endif  /* IF_RDR */

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值